New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
'MismatchReportingTestListener' has already been added and not removed using MockitoJUnitRunner #1767
Comments
A lot of updates exist between 1.10.19 and 3.0.0. Could you bisect the versions and figure out which minor version introduced the issue? |
2.26.0 looks like the one introducing this issue, all green in 2.25.1 |
@torakiki, can you provide us a simpler test that reproduces the issue? We are looking for a test without dependencies such as InitializeAndApplyJavaFxThreadRule, so that we can run & reproduce it in Mockito project. Thanks for reporting! |
@torakiki any luck? I'm having the same issue, upgrading from 2.23.4 @mockitoguy here's a simple test reproducing the issue in my case: @RunWith(MockitoJUnitRunner.class)
public class UuidHelperTest {
@Test
public void should_Get_16_Bytes_From_a_UUID() {
UUID uuid = UUID.randomUUID();
byte[] result = UuidHelper.getBytesFromUUID(uuid);
assertThat(result.length, is(16));
}
}
public class UuidHelper {
public static final int UUID_SIZE_IN_BYTES = 16;
public static byte[] getBytesFromUUID(UUID uuid) {
ByteBuffer bb = ByteBuffer.wrap(new byte[UUID_SIZE_IN_BYTES]);
bb.putLong(uuid.getMostSignificantBits());
bb.putLong(uuid.getLeastSignificantBits());
return bb.array();
}
} |
@SharonHart, this test works fine with current Mockito (3.0). Can you provide a test that fails with current Mockito? Thank you! |
@mockitoguy It works with the current Mockito version for me as well, on a clean project. |
@marcphilipp, @TimvdLippe Maybe this PR is related? Edit: I've reverted the commit locally and published to m2. Everything works now. Can this be reverted or checked for root cause? |
@SharonHart Which version of JUnit are you using? We had a regression since 4.13 which is why we made the changes. See junit-team/junit4#1599 |
@TimvdLippe JUnit 4.12 By the way, seems like what's causing the regression for me is the withBefores statement part, not the 'started' field removal in the RunListener. But, the regression you've mention was with the prior, right? |
@SharonHart Could you please provide a sample project so we can reproduce the issue? |
@marcphilipp Unfortunately, I can't. I tried to copy the test to a clean project and it didn't reproduce. |
Are you running tests in parallel or anything like that? |
Yes, in our CI pipeline. But reproduced locally with a single executor. It might be that the single one is running modules in parallel. I'm not sure. |
How are you running those tests? Maven Surefire? |
No, with gradle, without extra plugins |
What happens when you upgrade to JUnit 4.13-rc-1? |
Same. |
While I cannot provide a sample project to reproduce this issue, here are some observations that I made when running into the same issue:
public class JavaFXThreadingRule implements TestRule { /** * Flag for setting up the JavaFX, we only need to do this once for all tests. */ private static boolean jfxIsSetup; @Override public Statement apply(Statement statement, Description description) { return new OnJFXThreadStatement(statement); } private static class OnJFXThreadStatement extends Statement { private final Statement statement; public OnJFXThreadStatement(Statement aStatement) { statement = aStatement; } private Throwable rethrownException = null; @Override public void evaluate() throws Throwable { if(!jfxIsSetup) { setupJavaFX(); jfxIsSetup = true; } final CountDownLatch countDownLatch = new CountDownLatch(1); Platform.runLater(() -> { try { statement.evaluate(); } catch (Throwable e) { rethrownException = e; } countDownLatch.countDown(); }); countDownLatch.await(); // if an exception was thrown by the statement during evaluation, // then re-throw it to fail the test if(rethrownException != null) { throw rethrownException; } } protected void setupJavaFX() throws InterruptedException { long timeMillis = System.currentTimeMillis(); final CountDownLatch latch = new CountDownLatch(1); SwingUtilities.invokeLater(() -> { // initializes JavaFX environment new JFXPanel(); latch.countDown(); }); System.out.println("javafx initialising..."); latch.await(); System.out.println("javafx is initialised in " + (System.currentTimeMillis() - timeMillis) + "ms"); } } }
|
@hotzst Nice! I have managed to find that for me as well, a MethodRule we're implementing is what caused this. Question is, how should it be changed for the updated Mockito version. import org.joda.time.DateTimeZone;
import org.junit.rules.MethodRule;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;
import org.mockito.Mockito;
import org.mockito.internal.junit.MockitoTestListener;
import java.util.TimeZone;
/*
* When adding this rule to a Junit test, any @Test method annotated with @TimeZoned will be ran multiple times, each time
* with a different system timezone.
* This rule is useful to ensure you are handling all timezones correctly.
* Note: for Mockito, you may need to use Mockito.reset() if you are using verify().
* */
public class TimeZoneUpdateRule implements MethodRule {
final private TimeZone timeZone;
final private DateTimeZone dateTimeZone;
private final static String[] allTimeZones = {"UTC", "Asia/Jerusalem", "Europe/London", "US/Pacific", "EST5EDT", "US/Eastern",
"Australia/Sydney", "US/Central", "Asia/Tokyo", "America/Chicago", "GMT",
"Europe/Amsterdam", "Europe/Berlin", "Brazil/East", "Asia/Jakarta", "Europe/Athens",
"Australia/Queensland", "Asia/Singapore", "Asia/Bangkok", "America/Bogota",
"America/Los_Angeles", "Asia/Hong_Kong", "America/New_York",
"America/Argentina/Buenos_Aires"};
public TimeZoneUpdateRule() {
timeZone = TimeZone.getDefault();
dateTimeZone = DateTimeZone.getDefault();
}
public void reset() {
setTimeZone(timeZone, dateTimeZone);
}
protected void after() {
reset();
}
private void setTimeZone(String timeZoneID) {
setTimeZone(TimeZone.getTimeZone(timeZoneID), DateTimeZone.forID(timeZoneID));
}
private void setTimeZone(TimeZone timeZone, DateTimeZone dateTimeZone) {
System.setProperty("user.timezone", timeZone.getID());
TimeZone.setDefault(timeZone);
DateTimeZone.setDefault(dateTimeZone);
}
private static String[] getTimeZones() {
return allTimeZones;
}
@Override
public Statement apply(final Statement st, final FrameworkMethod method, Object target) {
return new Statement() {
public void evaluate() throws Throwable {
TimeZoned timeZoned = method.getAnnotation(TimeZoned.class);
if(timeZoned !=null){
String[] timeZones = timeZoned.timeZones().length > 0 ? timeZoned.timeZones() : getTimeZones();
applyAllTimeZones(st, timeZones);
}else{
st.evaluate();
}
}
};
}
private void applyAllTimeZones(Statement st, String[] timezones) throws Throwable {
try {
for (String tz : timezones) {
setTimeZone(tz);
st.evaluate();
}
}catch (AssertionError t){
throw new AssertionError(getMessage(), t);
}catch (Exception e){
throw new RuntimeException(getMessage(), e);
}
finally {
after();
}
}
private String getMessage() {
return "test failed for timezone [" + TimeZone.getDefault().getID()+ "]";
}
} |
Some rules evaluate the base statement multiple times, e.g. to execute tests repeatedly. The changes made in mockito#1672 led to an exception in such cases because the `MockitoListener` was registered multiple times. Now, we only add the listener the first time the statement is evaluated in order to restore the old behavior. Fixes mockito#1767.
Thanks for the additional info. I think #1821 should restore the old behavior. |
* Guard against multiple evaluations of before statement Some rules evaluate the base statement multiple times, e.g. to execute tests repeatedly. The changes made in #1672 led to an exception in such cases because the `MockitoListener` was registered multiple times. Now, we only add the listener the first time the statement is evaluated in order to restore the old behavior. Fixes #1767. * Reset listener when removing it
Thanks! |
* Guard against multiple evaluations of before statement Some rules evaluate the base statement multiple times, e.g. to execute tests repeatedly. The changes made in mockito#1672 led to an exception in such cases because the `MockitoListener` was registered multiple times. Now, we only add the listener the first time the statement is evaluated in order to restore the old behavior. Fixes mockito#1767. * Reset listener when removing it
Mockito 3.0.0, AdoptOpenJDK 11.0.4, Linux Mint
(same as any question on stackoverflow.com)
I migrated from 1.10.19 to the 3.0.0 version and I have few tests using the MockitoJUnitRunner which are failing with the following stacktrace:
It seems something internal, I didn't add or remove any
MismatchReportingTestListener
and moreover the same code was working with the 1.10.19 and is working if I remove theMockitoJUnitRunner
and replace the@Mock
annotation with aMockito.mock
in a@Before
method.The text was updated successfully, but these errors were encountered: