小编典典

Spock中最终类的模拟实例在测试和开发代码中的行为有所不同

java

在我的JavaFX应用程序中,我正在使用Spock和Groovy进行测试。我一直致力于WebBrowserController照顾我的JavafX
WebView组件。我想测试一些功能,这些功能取决于的当前位置和文档WebView

WebBrowserController的相关部分:

public WebEngine getEngine() {
    return panel.getWebView().getEngine();
}

这就是我WebBrowserController为测试创建实例的方式。请注意,GroovyMock我在这里使用的-
普通语言Mock(...)不适用于最终课程,WebEngine而是最终课程。

WebBrowserController getMockedControllerWithDocument(Document document) {
    WebBrowserController controller = Mock(WebBrowserController)
    controller.getEngine() >> GroovyMock(WebEngine) {
        getDocument() >> document
        getLocation() >> "some random string"
    }

    controller
}

下面的行正在测试中,并且中断。我希望返回“一些随机字符串”,但我只是通过了失败的测试和NPE。

String url = controller.get().getEngine().getLocation()

现在,有趣的部分-我WebEngine在两个地方检查了实例-
在结尾处getMockedControllerWithDocument和上面粘贴的行。我发现它引用了相同的对象。但是,当我在测试代码之外调用任何存根方法时,我被NPE击中-
getLocation()执行实际的实现而不是存根(原始方法不仅是简单的getter,而且使用介于两者之间的包装值)。

总结:为什么完全相同的对象在行为上会因调用方法的位置不同而不同?


阅读 256

收藏
2020-11-30

共1个答案

小编典典

因为GroovyMockGroovySpy并且GroovyStub仅对Groovy类起作用。当被Java类调用时,它们的行为类似于普通的Spock模拟。这是记录在这里

小费

什么时候应该把Groovy的嘲弄胜过常规的嘲弄?当规范下的代码用Groovy编写并且需要某些独特的Groovy模拟功能时,应使用Groovy模拟。
当从Java代码调用时,Groovy模拟将表现得像常规模拟一样。

请注意,仅因为规范和/或模拟类型下的代码是用Groovy编写的,所以不必使用Groovy模拟。除非有具体的理由使用Groovy模拟,否则最好选择常规模拟。

2020-11-30