In writing unit tests, for each object that the unit interacts with, I am taking these steps (stolen from my understanding of JBrains' Integration Tests are a Scam):
My question comes around when I decide to refactor an object that has responses mocked in step 2. If I change the way the object responds to a call, none of the tests that other objects have for that call will fail because they have all been mocked to match the old style. How do you keep mocks up to date with the objects they are mocking? Is there a best practice for this? Or have I completely misunderstood things and am doing it all wrong?
Learn more. Mocking is the creation of an object that mimics another and sets expectations concerning its behavior. In testing, mocking replicates the behavior of a service, object, or process. There are a number of benefits that result from replacing an object with a mock for testing purposes.
Mocks and stubs are very handy for unit tests. They help you to test a functionality or implementation independently, while also allowing unit tests to remain efficient and cheap, as we discussed in our previous post.
A mock object makes use of the same interface as the element of code it is intended to imitate and is often used in unit testing to scrutinize the performance of an actual object.
I do it this way.
Suppose I have to change the responses from interface method foo()
. I gather all the collaboration tests that stub foo()
in a list. I gather all the contract tests for method foo()
, or if I don't have contract tests, I gather all the tests for all the current implementations of foo()
in a list.
Now I create a version control branch, because it'll be messy for a while.
I @Ignore
(JUnit speak) or otherwise disable the collaboration tests that stub foo()
and start re-implementing and re-running them one by one. I get them all passing. I can do this without touching any production implementation of foo()
.
Now I re-implement the objects that implement foo()
one by one with expected results that match the new return values from the stubs. Remember: stubs in collaboration tests correspond to expected results in contract tests.
At this point, all the collaboration tests now assume the new responses from foo()
and the contract tests/implementation tests now expect the new responses from foo()
, so It Should All Just Work.(TM)
Now integrate your branch and pour yourself some wine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With