how to avoid returning mocks from a mocked object list
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)
Most of the time, if I need a mock to return another mock, I find a dependency that makes more sense in the other direction. Stated differently, mock-returning-mock usually points to a violation of the Dependency Inversion Principle.
One common exception: a factory that creates objects (as opposed to a "holder" that simply returns the same object each time). If I need to create multiple objects of the same type during my lifetime, then I might need to depend on an ObjectFactory
and invoke #createObject()
, then perhaps set expectations on the Objects. Even so, I would question this. It might be possible for something else one level up the call stack to create Object
s for me and give them to me as needed.
In the ObjectHolder
case, rather than depending on the ObjectHolder
to get the Object
, I prefer to depend on the Object
directly and force my caller to give it to me however it wants. This respects the desirable design property of context independence.
One specific version of this issue is the "Virtual Clock" pattern. Sometimes you need to depend on virtual clock, but often it's better simply to demand a timestamp ("Instantaneous Request" pattern) or, at worst, a stream of timestamps, wherever that comes from. Tests could provide a controled stream of convenient, hardcoded timestamps, but it's also easy to turn the system clock into a stream of timestamps.
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.
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.