Fixes #2648 : Add support for customising strictness via @Mock annotation and MockSettings#2650
Fixes #2648 : Add support for customising strictness via @Mock annotation and MockSettings#2650TimvdLippe merged 5 commits intomockito:mainfrom sivaprasadreddy:add-strictness-support
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2650 +/- ##
============================================
- Coverage 86.24% 86.22% -0.03%
- Complexity 2761 2763 +2
============================================
Files 314 314
Lines 8282 8290 +8
Branches 1031 1031
============================================
+ Hits 7143 7148 +5
- Misses 872 873 +1
- Partials 267 269 +2 ☔ View full report in Codecov by Sentry. |
TimvdLippe
left a comment
There was a problem hiding this comment.
Nice work! It's already looking good, mostly some nits. After that, this is ready to merge 🎉
| * Mock will have custom strictness, see {@link MockSettings#strictness(Strictness)}. | ||
| * For examples how to use 'Mock' annotation and parameters see {@link Mock}. | ||
| * | ||
| * @since 4.5.2 |
There was a problem hiding this comment.
Nit: @since 4.6.0 since we will include this in the next minor release
|
|
||
| /** | ||
| * Specifies strictness level for the mock. | ||
| * The default strictness level is STRICT_STUBS |
There was a problem hiding this comment.
Nit: the default is the default of the runner. If you use the lenient runner, it will be lenient. I suggest to formulate it the following way:
The default strictness level is determined by the rule/runner used. If you are using no rule/runner, the default strictness level is LENIENT.
| * Sets strictness level for the mock, e.g. having {@link Strictness#STRICT_STUBS} characteristic. | ||
| * For more information about using mocks with custom strictness, see {@link MockSettings#strictness(Strictness)}. | ||
| * | ||
| * @since 4.5.2 |
| * <h3 id="52">52. <a class="meaningful_link" href="#mockito_strictness" name="mockito_strictness"> | ||
| * New strictness attribute for @Mock annotation and <code>MockSettings.strictness()</code> methods (Since 4.5.2)</a></h3> | ||
| * | ||
| * By default Mocks use Strict stubbing and now you can customize the strictness level |
There was a problem hiding this comment.
Nit: mocks by default are lenient. I would omit that part altogether and reword it to:
You can now customize the strictness level for a single mock, either using `@Mock` annotation strictness attribute or using `MockSettings.strictness()`. This can be useful if you want all of your mocks to be strict, but one of the mocks to be lenient.
|
|
||
| // but regular mock throws: | ||
| Assertions.assertThatThrownBy( | ||
| new ThrowableAssert.ThrowingCallable() { |
There was a problem hiding this comment.
Nit: I think we can use a lambda here, can we not?
() -> ProductionCode.simpleMethod(regularMock, "4")| when(regularMock.simpleMethod("3")).thenReturn("3"); | ||
| when(strictMock.simpleMethod("2")).thenReturn("2"); | ||
|
|
||
| // then lenient mock does not throw: |
There was a problem hiding this comment.
Same here, let's have 3 separate 3 test cases here.
There was a problem hiding this comment.
Separated this into multiple tests.
TimvdLippe
left a comment
There was a problem hiding this comment.
Thanks for the PR and great implementation 🎉
| } | ||
|
|
||
| @Test | ||
| public void mock_is_strict_with_default_settings() { |
There was a problem hiding this comment.
Quick Q - was it intentional for this to change mocks defined by mock(Blah.class) i.e with no rule/Junit MockitoSettings to strict by default?
I believe the previous behaviour was lenient by default?
There was a problem hiding this comment.
We have not changed the behavior here. This test is using a Strict rule explicitly (https://github.com/mockito/mockito/pull/2650/files/d0907808e9fce24f6dcddc94d1ea2c3ebfa15676#diff-3040268f6b18ef562dd495ac7fc13465723311889d5f326bfb615cc3aed37415R21) to verify that we handle that case correctly.
In case you are hitting any regressions, please file a new issue. You are most likely running into a different problem.
There was a problem hiding this comment.
OK, thanks. We definitely have regressions (previously lenient mocks now behaving as strict) but I may have misidentified the possible cause. Will need to dig further if I get time.
There was a problem hiding this comment.
Another person has beat me to raising it at #2656 but this seems to be the same issue we are having.
## Changes - **mockito: 4.4.0 -> 4.6.1** (https://github.com/mockito/mockito/releases) Most important updates: - Fixes mockito/mockito#2648 : Add support for customising strictness via @mock annotation and MockSettings mockito/mockito#2650 ## Why is this change needed? According to the [Mockito documentation](https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#when(T)) : > Although it is possible to verify a stubbed invocation, usually it's just redundant. Let's say you've stubbed foo.bar(). If your code cares what foo.bar() returns then something else breaks(often before even verify() gets executed). If your code doesn't care what get(0) returns then it should not be stubbed. While working on the [Replace EasyMock and PowerMock with Mockito for StreamsMetricsImplTest ](https://issues.apache.org/jira/browse/KAFKA-12947) I noticed that described behavior wasn't applied when you create a new `mock` like this. ```java final Metrics metrics = mock(Metrics.class); when(metrics.metric(metricName)).thenReturn(null); ... invoke SUT verify(metrics).metric(metricName); // this should be redundant (according to docs) ``` After further investigation I figured out that described behaviour wasn't implemented until`v4.6.1`. With this change we are now able to mock objects like this: ```java Foo explicitStrictMock = mock(Foo.class, withSettings().strictness(Strictness.STRICT_STUBS)); ``` - link to docs: [MockSettings.html#strictness](https://javadoc.io/static/org.mockito/mockito-core/4.6.1/org/mockito/quality/Strictness.html#STRICT_STUBS) It looks like I can accomplish the same thing by using the `@RunWith(MockitoJUnitRunner.StrictStubs.class) ` instead of the `@RunWith(MockitoJUnitRunner.class)` so mockito dependency version update is not mandatory, but it would be nice to stay up-to-date and use the latest version (it's up to MR reviewer to decide if we are going to merge this now, or just close the MR and update mockito version later). Reviewers: Ismael Juma <ismael@juma.me.uk>
## Changes - **mockito: 4.4.0 -> 4.6.1** (https://github.com/mockito/mockito/releases) Most important updates: - Fixes mockito/mockito#2648 : Add support for customising strictness via @mock annotation and MockSettings mockito/mockito#2650 ## Why is this change needed? According to the [Mockito documentation](https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#when(T)) : > Although it is possible to verify a stubbed invocation, usually it's just redundant. Let's say you've stubbed foo.bar(). If your code cares what foo.bar() returns then something else breaks(often before even verify() gets executed). If your code doesn't care what get(0) returns then it should not be stubbed. While working on the [Replace EasyMock and PowerMock with Mockito for StreamsMetricsImplTest ](https://issues.apache.org/jira/browse/KAFKA-12947) I noticed that described behavior wasn't applied when you create a new `mock` like this. ```java final Metrics metrics = mock(Metrics.class); when(metrics.metric(metricName)).thenReturn(null); ... invoke SUT verify(metrics).metric(metricName); // this should be redundant (according to docs) ``` After further investigation I figured out that described behaviour wasn't implemented until`v4.6.1`. With this change we are now able to mock objects like this: ```java Foo explicitStrictMock = mock(Foo.class, withSettings().strictness(Strictness.STRICT_STUBS)); ``` - link to docs: [MockSettings.html#strictness](https://javadoc.io/static/org.mockito/mockito-core/4.6.1/org/mockito/quality/Strictness.html#STRICT_STUBS) It looks like I can accomplish the same thing by using the `@RunWith(MockitoJUnitRunner.StrictStubs.class) ` instead of the `@RunWith(MockitoJUnitRunner.class)` so mockito dependency version update is not mandatory, but it would be nice to stay up-to-date and use the latest version (it's up to MR reviewer to decide if we are going to merge this now, or just close the MR and update mockito version later). Reviewers: Ismael Juma <ismael@juma.me.uk>
This PR fixes the issue #2648.
This is to add support for customising strictness level for mock using @mock annotation or MockSettings.
Example 1:
Example 2: