views:

147

answers:

3

I'm trying out mock/responsibility driven design. I seem to have problems to avoid returning mocks from mocks in the case of objects that need a service to retrieve other objects.

An example could be an object that checks whether the bills from last month are paid. It needs a service that retrieves a list of bills. So I need to mock that billRetrievalService in my tests. At the same time I need that BillRetrievalMock to return mocked Bills (since I don't want my test to rely on the correctness of the Bill implementation).

Is my design flawed? Is there a better way to test this? Or is this the way it will need to be when using finder objects (the finding of the bills in this case)?

side note: althout Bill might be a value object candidate, the wider problem still remains when the collections aren't containing value objects (eg Users).

+4  A: 

Mock returning mocks is a strong code smell - a possible problem with the design. It could be that the Bills should be immutable values objects which should not be mocked. Or there is some confusion with the design and the responsibilities of the classes.

The book Growing Object-Oriented Software, Guided by Tests and paper Mock Roles, not Objects from the inventors of mock objects are worth reading.

Esko Luontola
I own a copy of the book and have read the paper. What I want to avoid are tests that fail and I have to wonder where if the failure comes from the isPaid logic in the Bills. Not mocking value objects seems sound when they are really simple.
koen
+3  A: 

Usually when I mock I end up having a triad of objects. The first object would be a coordinator BillsPaidLastMonthCoordinator this object has two dependencies BillRetrievalService and BillPaidValidator.

You would mock the two dependencies and your test would be for the interaction of retrieval and passing bills to the validation. So for this test you will not care what the data is. This helps separate responsibilities. Your original object was responsible for retrieving Bills and then seeing if it was a isPaid Bill.

With the way you described the problem you can end up is a noisy and brittle test. The brittleness comes from it being able to be broken in two ways.

With the corrdinator, it doesn't have to change if Bill implementation changes, Just the objects that actually use a Bill. My 2centavos.

[EDIT]

This is more aligned with using event handlers (the coordinator)

Gutzofter
+1  A: 

As the Way of the Testuvius advices, no principle, however good, should be taken absolutely and so it is also with the rule that you shouldn't need mocks returning mocks, there are cases when this is quite suitable.

As Gutzofter suggests, you could break your object into two, one for the actual validation and another one for retrieval of the bills to validate. The advantage of this "single responsibility only" principle application is that the validator would be more generic and reusable. On the other hand, if you only have this simple use case and no special need for the higher reusability, it's a very pragmatic to keep the retrieval and validation in a single class. Layering, explosion of the number of objects etc. unjustified by a real need and a real benefit, done only for the sake of satisfying an abstract principle, isn't good. You always have to weight the pros and cons and the reality rarely is simple and as beautiful as we would like :-) Great examples of this pragmatic approach are in Adam Bien's Real World Java EE Patterns - Rethinking Best Practices.

Jakub Holý