Search code examples
groovyspockjmockit

JMockit MockUp persisting between Spock tests


I'm using a Spock test written in Groovy to test some Java code. I'm using JMockit to mock methods in the java code, as Spock only handles mocking Groovy classes. I'm running into a problem where a JMockit MockUp is persisting between tests. Such a mock instance should only exist for the test (per JMockit documentation), but this isn't working, and I imagine it's because it's not using the JMockit test runner, and rather the Spock test runner.

Here is the simplest example of the problem I'm facing. I have a simple method returning a string, I can change the return value of the method with MockUp but it still exists for the third test, which doesn't expect it to be used.

Java Class

public class ClassToTest {
    public String method() {
        return "original";
    }
}

Spock Test

class ClassToTestSpec extends Specification {
    void "first test"() {
        when:
        String result = new ClassToTest().method()

        then:
        result == "original"
    }

    void "second test"() {
        setup:
        new MockUp<ClassToTest>() {
            @Mock
            public String method() {
                return "mocked"
            }
        }

        when:
        String result = new ClassToTest().method()

        then:
        result == "mocked"
    }

    void "third test"() {
        when:
        String result = new ClassToTest().method()

        then:
        result == "original"
    }
}

The third test fails, because ClassToTest.method() still returns the String "mocked" rather than "original". Using a debugger I have validated that the Mocked method is called twice.

Question

Is there any way to manually remove a class MockUp in JMockit? Thanks.


Solution

  • You can call the MockUp.tearDown method on the created mockup object, to manually undo its effects.