0

I would like to be able to do some unit testing during development in order to catch potential errors when extending/changing the way a given web service (endpoint) works.

I have been looking at EasyMock, and this seems like a viable way to go - but!... I'm using maven (2.0.9) and would like to test e.g. with mvn test, but this requires that my backend is running or that I use EasyMock - which then requires that I can connect to a database (thus this needs some mocking as well). The web services I currently have all retrieve data from a backend base...

As I have 15 or so web services used by different parts of the organization in different versions I would very much like to be able to test that changes doesn't break older versions.

I cannot believe that I'm the first person to have this problem, so any hints, tips, or likewise would be much appreciated.

sunlock
  • 212
  • 5
  • 17
  • Sorry, what your problem really is about? Are you looking for best practice/solution in mocking databases? – Michał Kalinowski Apr 17 '12 at 08:19
  • I would like to test my backend by mocking my endpoint. This I can do, but since my backend uses a database I must also mock this (that is, mocking my mocked object). Otherwise I might have missed something important about mocks... :) – sunlock Apr 17 '12 at 08:31
  • I don't got this "mocking mocked object" and still the question itself. You don't provide any mocks for other mocks. Mock is just quick implementation of some interface that doubles a real implementation and is able to verify interaction with itself (that's the main difference between mocks and other types of test doubles). You are really not interested in mocked object's real dependencies since you're in fact providing own implementation (with some help from mocking framework). – Michał Kalinowski Apr 17 '12 at 08:46
  • That was what I thought, but I guess something must have gone wrong then, because when I "mockClient.sendRequest(withPayload(requestPayload)).andExpect(payload(responsePayload));" (easymock) it will execute the backend code, which then throws a NPE due to no database... I'll give it a try again :) – sunlock Apr 17 '12 at 09:15
  • It shouldn't go wrong since you're interacting with mock, which behave exactly as you had told it to behave. If you told it to return `responsePayload` on `sendRequest(requestPayload)` invocation, that's exactly what it'll do. Real implementation probably does many complicated thing under cover, but the mock just return your crafted, hard-coded value (or throws an exception, or do whatever you want) and that's really enough to satisfy a need for interaction. It seems that you really don't have any problem. You just don't believe it's so simple. :) – Michał Kalinowski Apr 17 '12 at 09:24

1 Answers1

1

After comment-based talk :P, it seems that there's no problem actually. The key thing was to understand that some component's dependencies (like database) are just its real implementation dependencies and are not part of its interface. And mocking is about providing alternative implementation, to just satisfy a need for interaction.

In general, as you mentioned, all stuff you depend on in backend need to be mocked (or doubled in general) when unit testing, no matter what this stuff really is. If you depend on some external endpoint, you have to mock it. If you depend on RDBMS, you can mock it too, but probably better test double here would be fake instead of mock, so you can use some in-memory database (like HSQL or H2), assuming you're not using vendor-specific, native SQL in your code. In fact, you're still providing some own, usually simplified implementation of some interfaces, but nowadays you use mocking framework for this. Some time ago, developers write own, hand-crafted mock classes. Even today, it's sometimes really good idea to made own mock without help of mocking framework. Personally I encounter such special situation where this approach fits pretty well.

By the way, two more things. If you consider doing some integration testing as well, Spring WS since 2.0 version provides module spring-ws-test that supports this pretty well by providing really fluent API. For more info look at Spring WS docs, if you're interested. Second thing, if you're just starting with mocking in general, also consider using Mockito. In my opinion, it's really good as well. To be honest, EasyMock is my personal default choice for mocking lib, but I found Mockito similarly easy and powerful. As far as I know, it's prefered by many developers as well and nowadays it's probably more sexy :P.

Michał Kalinowski
  • 16,925
  • 5
  • 35
  • 48
  • So the world isn't as cruel as I feared... Nice! And yes, just started mocking and I'm also looking at Mockito. I already did use spring-ws-test, but encountered the same problem as described above - thus not knowing how to handle the database. Thanks for the tips and ideas. Much appreciated! – sunlock Apr 17 '12 at 10:31
  • Yeah, `spring-ws-test` is support for *integration* testing. You don't mock components then, since you test your system already integrated and not just components in isolation. – Michał Kalinowski Apr 17 '12 at 10:52