JMockit MockUp 在 Spock 测试之间持久存在

4
我正在使用Groovy编写的Spock测试来测试一些Java代码。由于Spock只处理Groovy类,因此我使用JMockit来模拟Java代码中的方法。我遇到了一个问题,即JMockit的MockUp在测试之间持久存在。根据JMockit文档,这样的模拟实例应该仅存在于测试中,但这并没有起作用,我想这是因为它没有使用JMockit测试运行器,而是使用了Spock测试运行器。
下面是我面临的问题的最简单示例。我有一个简单的方法返回一个字符串,我可以使用MockUp更改方法的返回值,但它仍然存在于第三个测试中,而该测试不希望使用它。 Java类:
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"
    }
}

第三个测试失败了,因为ClassToTest.method()仍然返回字符串"mocked"而不是"original"。使用调试器,我已经验证Mocked方法被调用了两次。

问题

在JMockit中是否有手动删除一个类MockUp的方法?谢谢。


Spock 可以模拟 Java 和 Groovy 类。对测试类进行模拟是一种不好的做法,应该谨慎使用。 - Peter Niederwieser
感谢@PeterNiederwieser的回复,我无法使用正常的符号表示instance.method() >> result,您能指点我正确的方向吗? - mnd
算了,这个符号确实有效,我忘记用 Mock 实例化对象了,像这样 ClassToTest instance = Mock(ClassToTest)。现在要想办法将其变成部分模拟,可能需要使用 Spy。 - mnd
如果你绝对需要或想要一个半模拟对象,那么 Spy() 是最好的选择。通常情况下,重构被测试的代码或重新考虑测试的内容/方式会更好。 - Peter Niederwieser
2个回答

4
你可以在创建的模拟对象上调用MockUp.tearDown方法,手动撤销其效果。

太棒了!谢谢@Rogerio! - mnd
就我个人而言,在 Spock 测试中,tearDown 方法并没有成功。如果有人已经解决了这个问题,我想看一个示例规范。谢谢。目前,我正在避免在 Spock 中使用 Jmockit。 - keaplogik
1
从 JMockit 1.28 开始,这个答案已经不再有效,因为 MockUp#tearDown 已经被删除了。 - Vampire

1

这并不是对问题的确切回答——因为我仍然不知道JMockit的MockUp是否可以手动移除。但是感谢@PeterNiederwieser的评论,我发现你实际上可以为一个Java类创建部分模拟。以下是对上面第二个测试的更改。

void "second test"() {
    setup:
    ClassToTest test = Spy(ClassToTest) {
        method() >> "mocked"
    }

    when:
    String result = test.method()

    then:
    result == "mocked"
}

Peter提到需要重新考虑如何以及什么需要测试,如果需要Spy(),但对于我的用例,这是首选。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接