New Mockito stubbing api
See original GitHub issueTop Mockito priorities (equal importance):
I. Maximize test’s clarity II. Maximize test’s failure output (easy test failure debugging) III. Guide the engineer toward cleaner, higher quality tests that are easy to maintain
Use cases, in the order of importance.
- Unused stubbing is dead code, an irrelevant detail that clutters test’s clarity.
- Unintentionally unused stubbing can make test failures harder to debug.
- When the stubbed call needs to be verified, it is declared twice in test (violation of DRY principle).
Proposed solution
The solution consists of multiple changes. Perhaps it’s better to show the code first, then describe the changes.
//JUnit rule automatically fails when stubs are unused:
MockitoJUnit.rule().strict();
//Offer a way to make specific stubbings optional:
given(mock.foo(), optional()).willReturn("bar");
//Offer a way to validate stubs for users who don't use JUnit rules:
Mockito.validateStubs();
Summary:
- All stubbed method calls must be used (realized), otherwise the test fails.
- Test failure is triggered by JUnit rule or Runner
- When JUnit rule or runner is not used, new Mockito.verifyStubs() method can be used. The method is not intended for engineers to use in tests. It’s intended for framework integrators (TestNG runners) or a common base class.
- “optional” stubbings. Consider default stubbings that user may put in test constructor or setup method. Those default stubbings are used by most test methods but not all. This is a legit scenario that needs to be supported.
- verifyNoMoreInteractions() no longer includes used stubs for validation when strict rule / runner is in use.
Mockito 3:
- Strict rule by default
- verifyNoMoreInteractions() no longer includes used stubs for validation
Issue Analytics
- State:
- Created 8 years ago
- Comments:17 (11 by maintainers)
Top Results From Across the Web
Mockito (Mockito 4.9.0 API) - javadoc.io
The Mockito library enables mock creation, verification and stubbing. This javadoc content is also available on the https://site.mockito.org/ web page.
Read more >Stubbing and Mocking with Mockito and JUnit - Semaphore CI
Learn how to create true unit tests by mocking all external dependencies in your JUnit classes with the help of Mockito.
Read more >Mockito and Fluent APIs - Baeldung
Thankfully, Mockito provides a really neat feature called deep stubbing which allows us to specify an Answer mode when we create a mock....
Read more >How to Mock Objects and Stub Methods with Mockito?
This blog post provides a guide on how to Mock Objects and Stub Methods with Mockito. Discusses the two different approaches to stub...
Read more >Mockito framework site
Mockito is a mocking framework that tastes really good. It lets you write beautiful tests with a clean & simple API. Mockito doesn't...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
It’s unfortunate this isn’t slated for 2.0 anymore, these are the kinds of features I’m most interested in seeing, as they help keep the tests accurate and complete.
In most cases, I’d like my mocks to:
The lack of these kinds of features increases the time-cost of using Mockito because:
@szczepiq I’ve experimented with changing the default answer in Mockito 1.This interacts poorly with when/then style stubbing though. Workarounds are to (a) use do/when style, which loses compile time type safety on the returns, (b) temporarily disable the default answer behavior during setup, but this is a pain to manage and make sure you re-enable when done, or © wrap Mockito stubbing APIs to apply (b) automatically during the ongoing stubbing call.
This basically boils down to changing the answer behavior during stubbing to be different than a nonstubbing mock interaction.
I see Erik added some great comments whole I was writing this.
A separate point… I don’t think standard Mockito behavior needs to change, as there are legitimate uses for wanting mocks with null defaults. It would also be a huge shift for the user base.
That’s said, I personally find the most arguments for using loose mocks in tests so they are not over specified to be logically unsound. If you don’t know what was done with the mock, and you haven’t mocked a behavior, then usually follows that the test is of the feel-good variety and not very good. Ultimately you can’t really say what the code did other than it didn’t blow up, produced a particular result in an unknown context, or had a few interactions on a mock. It’s usually not possible to reason that there were no unexpected interactions that invalidate the test, or that the handwaving used when the test was first written still holds in the future. For these reasons I don’t use Mockito like many apparently do, I want my mocks absolutely specified and fully verified whenever possible. I blame my mathematics background for this desire for rigorousness.
When I don’t or can’t then I used Mockito like most people, but I make it clear in the test the intended bounds of this lack of rigorousness. Such tests are usually rather shallow and only exist to provide loose constraints on the behavior of the code. I usually think through such cases multiple times to ensure this is truly the proper strategy to use, as the test is inherently ill-defined and potentially invalid now or in the future, even it if it keeps on passing the entire time.