Reality Check: Legacy Code Kata with Mockito
I recently blogged about the Legacy Code Kata at Softwerkskammer Hamburg Dojo. Now it’s about time that the Kata passes the reality check. So I took some legacy code colleagues cursed about and started to write some tests strongly relying on mocking framework Mockito.
Mockito is great, …
Unlike the Coding Kata I relied on a mocking framework this time. It’s my favorite one: Mockito. So simply I mocked a page and some navigation object like this:
page = Mockito.mock(Page.class); navigation = Mockito.mock(Navigation.class); Mockito.when(page.getNavigation()).thenReturn(navigation);
This mocking was required deep in the callstack of the class under test.
but… The Problem
If this code will ever be refactored (actually I know that it soon will be) it might happen that the mocked call is actually not called anymore which makes the assumptions invalid and thus the result of the test is completely meaningless.
The Recommended Solution
If you are ever in need to mock some method calls you should verify that they actually got called. As this is a check of the assumptions made I recommend to place this in front of your test-assertions (as they are meaningless when these checks fail):
Mockito.verify(page, VerificationModeFactory.times(1)) .getNavigation();
If this fails it is most likely that you have to adopt your test rather than adopt your code.
times(1) could have been skipped here as this is the default. For this example
atLeastOnce() would have been more appropriate as it is just important that the mocking got used – not how many times.
Side Note: AssertionError
What is bad (at least in this use case) is that
Mockito.verify() raises an assertion error if the verification fails. But an assertion error is perceived as signal that something is wrong with the code under test. It would be better to have a “normal” exception here which would mark the test as “error” rather than “failure” which is more appropriate here as the test did not fail – it just did not match the assumptions.
If you have a huge set of stubbed method calls as above you can easily convert a copy of it to a verification using this regular expression replacement:
From: when\(([^.]+)\.(.*(?=\)\.then)).* To: verify($1, atLeastOnce()).$2;
The above example assumes static import for