Alexito's World

A world of coding 💻, by Alejandro Martinez

🔗 Linked post

Check out the linked article.

Abusing mocks

The post Mock yourself, not your tests immediately captured my attention just by saying "I feel like we abuse of them". As I've been having more and more the same feelings about mocks in my tests.

probably the primary reason for using mocks is to make a unit test more specific. Just testing exactly one piece of code, and thus, avoiding having to test things that (hopefully) are already tested.

Exactly the reason why I use them. Having specific unit tests means that you have to mock any dependency that your ViewModel uses, DataProviders, formatters, etc. This gets tedious really quickly, as you spend more code setting up the test than actually testing what you care about. And not having this dependencies injected is not a solution I want to use.

This kind of testing also tends to check if certain methods on the mock are called. This is also problematic.

This kind of unit testing makes too many assumptions on how process() is implemented. Tightly coupling your tests with mocks, causes refactors to be painfull. As soon as you change a detail of the implementation your tests will break (which is not the same as to fail), with helpless tracebacks about functions that were not called, or mocks that fail to be applied because some method doesn't exist anymore

The post also talks about mocks being too permissive and hiding errors. I totally agree. I've recently switched to use OCMock and that framework uses nice mocks by default, which means that if a mock receives a method call that is not expecting it doesn't complain. This has a great advantage, tests are easier to setup. But it can hide real problems in your code.

Before I used Kiwi and in there you have to explicitly stub any method you are expecting (or explicitly ask the framework to ignore the rest of the methods), which means that you have to be aware of everything is going on and is really easy to detect misbehaviour. Is more work to setup, but it's safer. Although this goes back to the first point of the post, any future change in the internal behaviour of an object will likely mean that your tests don't work anymore, which is no good.

I really like testing and TDD but I still have to find the sweet spot in testing some parts of an App. That said, other kinds of code are amazing candidates to use TDD.