Why does JMockit expectations block throws IllegalMonitorStateException?

Viewed 179

I use JMockit to mock some instance for junit test. But I found it is not execute because the JMockit expecataions block always throws IllegalMonitorStateException.

For example the source code is:

 public class ForTest {
    public static class A {
        public String getStr() {
            return "a";
        }
    }

    public String getStrFrom(A a) {
        return a.getStr();
    }
}

And the junit test code is:

public class ForTestTest {
    @Tested
    ForTest forTest;

    @Injectable
    ForTest.A a;

    @Test
    public void test_str() {
        new Expectations() {{
            a.getStr();
            result = "b";
        }};

        Assertions.assertEquals("b", forTest.getStrFrom(a));

        new Verifications() {{
            a.getStr();
            times = 1;
        }};
    }
}

When I run the test, there is an exception:

java.lang.IllegalMonitorStateException
at com.huawei.genexcloud.nsp.worker.ForTestTest$1.<init>(ForTestTest.java:30)
at com.huawei.genexcloud.nsp.worker.ForTestTest.test_str(ForTestTest.java:27)
Suppressed: Missing 1 invocation to:
com.huawei.genexcloud.nsp.worker.ForTest$A#getStr()
on mock instance: com.huawei.genexcloud.nsp.worker.ForTest$A@589b3632
Caused by: Missing invocations
at com.huawei.genexcloud.nsp.worker.ForTest$A.getStr(ForTest.java)
at com.huawei.genexcloud.nsp.worker.ForTestTest$1.<init>(ForTestTest.java:28)
at com.huawei.genexcloud.nsp.worker.ForTestTest.test_str(ForTestTest.java:27)

My IDE is intellij idea 2020.2.3. My JDK is OpenJDK 1.8 and the version of JMockit is 1.49. I think it is something wrong in my ide settings but I don't know how to fix it.

I try to run the test with gradle. It works well.

2 Answers

This worked for me OK when running in Eclipse. And I don't see anything obviously wrong with the syntax.

If it works at the command line but not in the IDE, then odds are there is a config issue in the IDE. Remember that you have to configure the javaagent to get jmockit to work - that may be an extra step in the IDE.

The other trick that may help you out is that you can consolidate "Verifications" into "Expectations". It's a bit less code to write.

    @Test
public void test_str() {
    new Expectations() {{
        // provides an expected value *AND* ensures called once-and-only-once
        a.getStr();
        times = 1;
        result = "b";
    }};

    Assertions.assertEquals("b", forTest.getStrFrom(a));
}

Ensure there is only one javaagent:jmockit-xxx.jar being added to the Java command line

Related