Skip to content
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

Obscure issue with mockito-inline: mock object in a test seems to be corrupting mock in later test #2499

Closed
smas321 opened this issue Dec 7, 2021 · 11 comments · Fixed by #2505
Assignees

Comments

@smas321
Copy link

smas321 commented Dec 7, 2021

This is a very obscure issue, happens only when the planets are aligned. Can you possibly tell me if this is an issue with mockito-inline or if I'm doing something wrong. If its an issue, is there a workaround?

I've simplified what I'm seeing as much as possible. I have 2 tests: Test1 and Test2. I mock MyClass in Test1 (calling clearInlineMocks in @afterclass). In Test2, I mock TestSubInterface which extends TestInterface, which creates an instance of the class I mocked in Test1. The issue is that the constructor for MyClass is not being called when mocking the TestSubInterface in Test2 (I guess because mockito-inline still sees MyClass as a mock from the previous test?). I initialize a variable in the MyClass constructor and later throw an error if it hasn't been initialized, resulting in a java.lang.NoClassDefFoundError when mocking.

HOWEVER, the constructor for MyClass IS called when:

  • I mock TestInterface directly instead of TestSubInterface OR
  • I do NOT have a default method defined in TestInterface OR
  • I use mockito-core instead of mockito-inline

Here are the details:

java.lang.NoClassDefFoundError: Could not initialize class TestSubInterface$MockitoMock$1328129486
        at jdk.internal.reflect.GeneratedSerializationConstructorAccessor2.newInstance(Unknown Source)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
        at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:48)
        at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
        at org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:21)
        at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.doCreateMock(InlineByteBuddyMockMaker.java:360)
        at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createMock(InlineByteBuddyMockMaker.java:318)
        at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:53)
        at org.mockito.internal.MockitoCore.mock(MockitoCore.java:62)
        at org.mockito.Mockito.mock(Mockito.java:1951)
        at org.mockito.internal.configuration.MockAnnotationProcessor.processAnnotationForMock(MockAnnotationProcessor.java:66)
        at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:27)
        at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:24)
        at org.mockito.internal.configuration.IndependentAnnotationEngine.createMockFor(IndependentAnnotationEngine.java:46)
        at org.mockito.internal.configuration.IndependentAnnotationEngine.process(IndependentAnnotationEngine.java:73)
        at org.mockito.internal.configuration.InjectingAnnotationEngine.processIndependentAnnotations(InjectingAnnotationEngine.java:73)
        at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:47)
        at org.mockito.MockitoAnnotations.openMocks(MockitoAnnotations.java:82)
        at org.mockito.internal.runners.DefaultInternalRunner$1$1.evaluate(DefaultInternalRunner.java:49)
        at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
        at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
        at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
        at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:99)
        at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:105)
        at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:40)
        at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
        at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
        at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
        at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.Silent.class)
public class Test1 {

    @Mock
    private MyClass foo;

    @AfterClass
    public static void after() {
        Mockito.framework().clearInlineMocks();
    }

    @Test
    public void test() {
        System.out.println("test1!");
    }
}
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class Test2 {

    @Mock
    TestSubInterface testInterface;

    @Test
    public void test() {
        System.out.println("test2!");
    }
}
public interface TestSubInterface extends TestInterface {
}
public interface TestInterface {

    MyClass foo = MyClass.createMyNumber(8, "someType").convertTo("someOtherType");

    default boolean someMethod() {
        return true;
    }
}
public class MyClass {

    private final double num;
    private final String type;
    private Object someInternalObj;

    public static MyClass createMyNumber(double m, String  type) {
        return new MyClass(m, type);
    }

    public MyClass(double num, String type) {
        this.num = num;
        this.type = type;
        someInternalObj = new Object();
        System.out.println("MyClass!!!!!!");
    }

    public MyClass convertTo(String to) {
        if(someInternalObj == null)
            throw new RuntimeException("someInternalObj was null");
        return MyClass.createMyNumber(num, to);
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>Test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>15</maven.compiler.source>
        <maven.compiler.target>15</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-inline</artifactId>
            <version>3.9.0</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>

I'm on windows 10

java --version
java 17.0.1 2021-10-19 LTS
Java(TM) SE Runtime Environment (build 17.0.1+12-LTS-39)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.1+12-LTS-39, mixed mode, sharing)

check that

  • [ x] The mockito message in the stacktrace have useful information, but it didn't help
  • [ x] The problematic code (if that's possible) is copied here;
    Note that some configuration are impossible to mock via Mockito
  • [ x] Provide versions (mockito / jdk / os / any other relevant information)
  • [x ] Provide a Short, Self Contained, Correct (Compilable), Example of the issue
    (same as any question on stackoverflow.com)
  • [ x] Read the contributing guide
@raphw
Copy link
Member

raphw commented Dec 10, 2021

PR for fix is open.

@smas321
Copy link
Author

smas321 commented Dec 14, 2021

thx @raphw!

@smas321
Copy link
Author

smas321 commented Dec 15, 2021

hi @raphw do you have any indicative dates on when this bug would be released? or if its available in some other build I can try out

@raphw
Copy link
Member

raphw commented Dec 15, 2021

@TimvdLippe Any reason not to trigger a release some time soon?

@TimvdLippe
Copy link
Contributor

It's been about a month since we last released, so I will release one today. Thanks!

@raphw
Copy link
Member

raphw commented Dec 15, 2021

I'll do a BB release later today. It contains some Java 17 bug fixes, so you might just wait on that.

@TimvdLippe
Copy link
Contributor

Ha. I just started the release procedure, but I canceled the GitHub action again. Will wait for the BB release 👍

@smas321
Copy link
Author

smas321 commented Dec 15, 2021

many thanks!

@raphw
Copy link
Member

raphw commented Dec 15, 2021

Central is timeouting a lot since everybody tries to fix their log4shell issues. Let's delay a few days.

@TimvdLippe
Copy link
Contributor

I updated our version of BB and starting a new release now.

@TimvdLippe
Copy link
Contributor

4.2.0 is being published to Maven Central atm: https://github.com/mockito/mockito/actions/runs/1587549926

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants