How to make your code more unit test friendly (and better)
You just simply split your code into small classes and methods while ensuring you follow the principles of Separation Of Concerns and Single Responsibility.
If you have a big method you want to unit test, you should use the “Extract Methods” refactoring. Simply select some code that does “one thing” and extract that code into a new method. Then make a unit test for the method.
Ideally each class/method in a system should have one single responsibility and each method in a class should only do one small task.
In practice, not every method in a system can be a simple small one. Often, there are methods that have a large and complex responsibility. E.g. a
A way to avoid a Unit Test Hell is to ensure that it does not have value to unit test a method like
This can be done by letting the method pass on all important work (e.g. work that is worth a unit test) to other methods.
This is exactly what we are doing for method A in the diagram below.
A1 is the method before refactoring. A2 is the same method after refactoring. 3 code segments (B, C and D) are extracted into new methods.
The method (A2) is now calling other methods (B, C and D) to do the actual work and there is now no value in making a unit test for A2 (Perhaps an integration test, but not a unit test). Instead you should of course consider if it has good value to make unit tests for method B, C and D.
If e.g. method B seems complex to unit test, you should also consider extracting code segments in B and make B “not unit test worthy”.This is so simple and I like to keep stuff simple.
If you "extract" your code correctly and you have focus on testing business rules (in a unit test way - not in an integration test way), then you do not really need the complexity of stuff like mocking, stubbing and dependency injection. Does anyone dare to prove me wrong on this?