Mockitomedium3-5 years
After a refactor, twelve tests fail with `UnnecessaryStubbingException` even though no assertion changed. A teammate proposes `@MockitoSettings(strictness = Strictness.LENIENT)` on the base class. What is Mockito telling you, why is lenient the wrong default, and what do these failures usually reveal about the tests?
MockitoExtension runs with strict stubs: after each test it checks every when(...) the test set up, and a stub that no code path used fails the test. After a refactor that means the code no longer calls what the test scripted, so the test's setup describes an implementation that no longer exists. Either the stub is dead and should go, or the test is no longer exercising the path its name claims, and it has been passing for the wrong reason. Going lenient silences exactly that signal for every test in the suite. Fix each test: delete dead stubs, use lenient() on the one stub that genuinely is optional, and ask why the tests broke at all when behaviour did not change.
PreviousA service has 800 unit tests that run in 4 seconds and 40 browser tests that take 25 minutes, and nothing in between. A repository query with a wrong `JOIN` shipped and was caught only by a browser test, three hours after the merge. Name the shape, explain why the unit tests could not have caught it, and say where you would add tests.Next A `@DataJpaTest` persists three orders with `TestEntityManager` and asserts on `findById` and a derived query. It is green, but in production the same repository fails: a native query uses `DISTINCT ON`, and an `@Convert`-mapped column reads back wrong. Also, an `@TransactionalEventListener(phase = AFTER_COMMIT)` handler is never invoked in any repository test. Explain all three with what the slice does by default.