繁体   English   中英

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

[英]Mocked instance of final class in Spock behaves differently in test and dev code

在我的 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,它在中间使用了一个包装值) .

总结一下:为什么完全相同的对象会根据调用其方法的位置而表现不同?

因为GroovyMockGroovySpyGroovyStub只能按您对 Groovy 类的预期工作。 当被 Java 类调用时,它们的行为就像普通的 Spock 模拟。 这是记录在这里

提示

Groovy Mock 什么时候应该比普通 Mock 更受欢迎? 当规范下的代码是用 Groovy 编写的并且需要一些独特的 Groovy 模拟功能时,应该使用 Groovy 模拟。 当从 Java 代码调用时,Groovy 模拟将表现得像常规模拟。 请注意,没有必要仅仅因为规范和/或模拟类型下的代码是用 Groovy 编写的就使用 Groovy 模拟。 除非您有使用 Groovy 模拟的具体理由,否则更喜欢常规模拟。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM