8

I just refactored many parts of code by simplifying things. Now I need to refactor the tests as well to make them green again, which is not that hard.

But now I struggle a bit as I saw that I don't need some of my .when() declarations anymore as these Mocks won't be called anymore. The thing is they don't make my test red, so I can only identify them by carefully going through each test and compare it to the code, which is kind of annoying and lead to letting it be like that.

Is there any possibilty to make unused .when()'s throwing an error or such? Like a verify which never happens? It would be enough to do it like in setUp: Mockito.enableDebugMode() or whatever, maybe there is such a possibility? ..

Best

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
BAERUS
  • 4,009
  • 3
  • 24
  • 39
  • Try to simply remove when() and run the test. If it becomes red, this 'when' is obviously required. – ponomandr Aug 29 '14 at 08:23
  • If you have re-factored your code and broken your tests then you're doing bad things. Your tests should remain green after re-factoring. If you re-factor in smaller steps then you can tackle your tests cases one at a time and wont find yourself in this dark place. Also your tests should be small and easy to understand otherwise your classes under test are doing too much. – Brad Aug 30 '14 at 11:09

5 Answers5

5

This feature has been added to Mockito 2.1.0 (https://github.com/mockito/mockito/issues/384).

The default JUnit Rule configuration is to log a warning in the console :

@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();

But you can even make your tests fail by increasing the strictness :

@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
Thomas Naskali
  • 551
  • 5
  • 19
  • Or get rid of the hints using `public MockitoRule mockitoRule = MockitoJUnit.rule().strictness(Strictness.LENIENT);` [Not Recommended] – ankur_kachru Jan 31 '19 at 05:44
  • Sometimes getting rid of the hints IS good. I have a test where part of a failure condition is IF a when().thenAnswer() condition is invoked. Without it, I would not know that something went bad. When the test passes, the when().thenAnswer() is not called and I get the Mockito message (looks like a Unit test Fail). – Brian Reinhold Mar 24 '19 at 15:20
4

Option 1 You can remove the calls to when() from your tests one at a time (as suggested by @ponomandr) until they fail. A failed test means you add the call to when() back into your test as it must be required.

Option 2 Although you could also approach this problem by adding verify() assertions for every call to when() (as suggested by @HansiKrankl) it means adding more code (fluff) to your test cases.

Option 3 As another alternative you can you use a code coverage tool like Emma whichi you can run from your IDE. It would then be the case of running the test and then seeing whether the calls are being made in your class under test.

Option 4 There are other suggestions around attempting to count the number of invocations.

Personally I would go with Option 1 and starting cleaning up the tests one by one. You will gain a better understanding of the tests looking at them one-by-one and it's an opportunity to clean them up so they are more maintainable.

Community
  • 1
  • 1
Brad
  • 15,186
  • 11
  • 60
  • 74
  • I have found Option 1 to work well, especially when you can alternate small refactorings with testing to reduce the noise. – cjstehno Apr 06 '15 at 21:31
0

Maybe you can add a verify() call for every when() call. So an Exception is thrown when the call is not executed?

If there is an automated solution for the problem, please leave a reply.

0

Hmm, what's about to use Mockito.verifyNoMoreInteractions(YOUR_MOCKS) ? It will throw exception in case some mock object was configured with Mockito.when() but no corresponding Mockito.verify() method has been called on this mock. Sure might lead to false positives but better then nothing.

Grigory
  • 465
  • 5
  • 16
0

In JUnit 5, unused/mismatched mockings will cause tests to fail if you annotate your test class with:

@ExtendWith(MockitoExtension.class)

This comes from the mockito-junit-jupiter dependency. You can view the source on GitHub: MockitoExtension.java

Matthew Read
  • 1,365
  • 1
  • 30
  • 50