dplavcic commented on code in PR #12459:
URL: https://github.com/apache/kafka/pull/12459#discussion_r933758267


##########
streams/src/test/java/org/apache/kafka/streams/state/internals/metrics/RocksDBMetricsRecorderTest.java:
##########
@@ -36,22 +38,23 @@
 import org.rocksdb.StatsLevel;
 import org.rocksdb.TickerType;
 
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.mock;
-import static org.easymock.EasyMock.niceMock;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertThrows;
-import static org.powermock.api.easymock.PowerMock.reset;
-import static org.powermock.api.easymock.PowerMock.createMock;
-import static org.powermock.api.easymock.PowerMock.mockStatic;
-import static org.powermock.api.easymock.PowerMock.replay;
-import static org.powermock.api.easymock.PowerMock.verify;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({RocksDBMetrics.class, Sensor.class})
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)

Review Comment:
   What do you think we use `@RunWith(MockitoJUnitRunner.StrictStubs.class)` 
which automatically detects stubbing argument mismatches instead of the 
`@RunWith(MockitoJUnitRunner.class)` 🤔 
   - 
https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/junit/MockitoJUnitRunner.html
   - 
https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/junit/MockitoJUnitRunner.StrictStubs.html
   - 
https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/quality/Strictness.html#STRICT_STUBS
   
   With `StrictStubs` we get (c/p from the 
[docs](https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/quality/Strictness.html#STRICT_STUBS)):
   > - Improved productivity: the test fails early when code under test invokes 
stubbed method with different arguments (see 
[PotentialStubbingProblem](https://javadoc.io/static/org.mockito/mockito-core/4.6.1/org/mockito/exceptions/misusing/PotentialStubbingProblem.html)).
   > - Cleaner tests without unnecessary stubbings: the test fails when unused 
stubs are present (see 
[UnnecessaryStubbingException](https://javadoc.io/static/org.mockito/mockito-core/4.6.1/org/mockito/exceptions/misusing/UnnecessaryStubbingException.html)).
   > - Cleaner, more DRY tests ("Don't Repeat Yourself"): If you use 
[Mockito.verifyNoMoreInteractions(Object...)](https://javadoc.io/static/org.mockito/mockito-core/4.6.1/org/mockito/Mockito.html#verifyNoMoreInteractions(java.lang.Object...))
 you no longer need to explicitly verify stubbed invocations. They are 
automatically verified for you.
   
   Note that once we migrate this test to use JUnit5, and we start using 
`@ExtendWith(MockitoExtension.class)` instead of the 
`@RunWith(MockitoJUnitRunner.class)` we will get `STRICT_STUBS` behavior 
out-of-the-box.
   
   ---
   
   Considering this test for example:
   ```java
       @Test
       public void 
shouldSetStatsLevelToExceptDetailedTimersWhenValueProvidersWithStatisticsAreAdded()
 {
           
doNothing().when(statisticsToAdd1).setStatsLevel(StatsLevel.EXCEPT_DETAILED_TIMERS);
   
           recorder.addValueProviders(SEGMENT_STORE_NAME_1, dbToAdd1, 
cacheToAdd1, statisticsToAdd1);
   
           
verify(statisticsToAdd1).setStatsLevel(eq(StatsLevel.EXCEPT_DETAILED_TIMERS));
       }
   ```
   
   - with `StrictStubs`, if someone changes what is passed to the 
`setStatsLevel()` method in production code, and hard-code it to, for example 
`statistics.setStatsLevel(StatsLevel.ALL);`, this test would fail **even 
without explicit verify** with following message:
   
   ```
   Unnecessary stubbings detected in test class: RocksDBMetricsRecorderTest
   Clean & maintainable test code requires zero unnecessary code.
   Following stubbings are unnecessary (click to navigate to relevant line of 
code):
     1. -> at 
org.apache.kafka.streams.state.internals.metrics.RocksDBMetricsRecorderTest.shouldSetStatsLevelToExceptDetailedTimersWhenValueProvidersWithStatisticsAreAdded(RocksDBMetricsRecorderTest.java:180)
   Please remove unnecessary stubbings or use 'lenient' strictness. More info: 
javadoc for UnnecessaryStubbingException class.
   ...
   ```
   
   Mockito documentation provides a good explanation of what is happening (and 
why verify step could be redundant):
   - 
https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#when(T)
   - 
https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#verify(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. 
   
   
   Note:
   - I'm not sure if Mockito docs links with `fragment/anchor` don't work just 
for me or for all 🤔 
   
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: jira-unsubscr...@kafka.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to