I am looking for a solution/pattern for the following unit testing case.
The case:
Let's pretend that we have three classes, A,B,C each with one method. A's method calls B's method which calls C's method. So, A->B->C. Each method take one input (Input A for method A, input B, input C). The resulting output of the call to method A, would be a tree structure such as:
Root (created from method A) -- Node B (created from method B) -- Node C1 -- Node C2 (both created from method C)
For me unit testing is about testing the output from input of a method in isolation. So, we would write unit tests for each of the methods above. Because the tests are written in isolation, we would mock the method B when writing unit tests for method A, and mock the method C when writing unit test cases for method B.
So far, all is good, we can write expectations on the output for each method to make sure that the resulting tree structure is respected.
The problem:
Let's now add another class which would call method B so that we also have the following call chain: D->B->C. The resulting root tree would look like this:
During the development, someone realise that the requirement for method A was misunderstood and the tree result should have looked like this:
Happily the developer would change the method C so that the output only returns one Node rather than two. He would change the unit tests so that it reflects those changes. However, method D requirements should not have changed, and the output of that method should still have Node C1 and Node C2.
The question:
How would you have written your unit tests so that the second developer would have been alerted of breaking change he would have introduced for method D? I would rather avoid integration tests which would seem the best fit here.
Thanks.
You should have a mix of "pure¹" unit tests, impure unit test, integration (external resource hitting) tests and full stack tests (UI down). "Pure" unit tests are not the end of testing.
So you will end up with some of the follow types of test for each feature you develop:
As long as you have some of the higher level test, they should fail even if test that hit A isolation don't.
¹ Just using the phrase "pure unit tests" as some people have it their heads that the definition a unit test is method in isolation
Ideally your unit test should penetrate all the way down to Class C. A unit test does not necessarily mean ONE METHOD on ONE CLASS. It just means that you can run it without needing other dependencies like libraries, or databases etc. Then you would need an integration test.
Your unit test should penetrate all the way to C, and when the requirement changes for A, then the unit test will break, and developer for D will know that something is wrong.
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