views:

49

answers:

3

Hi,

When I use Easymock(or a similar mocking framework) to implement my unit tests, I'm forced to do interaction-based testing (as I don't get to assert on the state of my dependencies. Or am I mistaken?).

On the other hand if I use a hand written stub (instead of using easymock) I can implement state based testing.

I'm quite unclear if I want to go with interaction based testing or state based testing.

I'm biased and I want to use Easymock, but I'm not sure if there would be any side-effects that I may have to face in the future.

Can anyone please throw some light on this?

Thanks in advance!

A: 

I'd say unit-testing concept is overrated. I very much like the idea of automated testing, but I don't like the artificial requirement that you only test one unit and not system/subsystem as a whole.

That said, you should test interaction when object is inherently build to interact with said dependency through interface and it is pretty much certain that there are/will be different implementations of that interface. In such case you really want to remove any implementation-details of particular interface implementation from consideration.

However, if there is an interface, but only "just in case of future expansion" — i.e. when there is no second implementation in a foreseeable future, I'd say it is fine to test object together with the only existing dependency implementation. Additional effort required to properly mocking the interface will probably give more bugs than benefits.

doublep
A: 

There is no reason you cannot do both. I find behavior-based or interaction-based testing using mocks saves a lot of boilerplate when all you want to do is test behavior. With hand-written stubs you end up with a lot of booleans indicating that a method was called that you have to then test for. That is redundant, brittle and quite a drag.

On the other hand, sometimes you do want to test state. For example, if the object under test's behavior needs to change based on the state of the candidate for mocking or stubbing, and there is some complex interaction to work out.

In that case, mocking frameworks can get in the way, and a hand-written stub makes managing the state much easier for the purposes of the test.

So the bottom line is that they are not mutually exclusive - use what makes sense for a given test. As long as each test is small and tests only one thing (as much as is reasonable) then you shouldn't find yourself in a situation where you started with a mock an suddenly find you have to do a bunch of effort to get things back to a stub.

Yishai
+2  A: 

You have to divide your objects into domainy value objects (which hold state and should be immutable) and services. Services are the things other objects should ask to perform a particular task, but your code shouldn't be concerned about how this task is performed. To test the service in isolation without testing its peers, use a mock.

Value objects, which may contain domain functionality such as calculations, should never be mocked, because their responsibility is calculating and not delegating.

In a well designed system, services should always be injected and never returned from other services, so generally speaking, mocks shouldn't return mocks.

rhys keepence