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

标签 java javafx groovy webview spock

在我的 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 的末尾和上面粘贴的行。我发现它引用了同一个对象。然而,当我在测试代码之外调用任何 stub 方法时,我遇到了 NPE - getLocation() 执行了实际的实现,而不是 stub (原始方法不仅仅是一个简单的 getter,它使用其间的包装值)。

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

最佳答案

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

TIP

When Should Groovy Mocks be Favored over Regular Mocks? Groovy mocks should be used when the code under specification is written in Groovy and some of the unique Groovy mock features are needed. When called from Java code, Groovy mocks will behave like regular mocks. Note that it isn’t necessary to use a Groovy mock merely because the code under specification and/or mocked type is written in Groovy. Unless you have a concrete reason to use a Groovy mock, prefer a regular mock.

关于java - Spock 中最终类的模拟实例在测试和开发代码中的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54180395/

相关文章:

java - 在不同 Java 类的方法中使用变量

javafx - 传递参数JavaFX FXML

java - 如何更改未选定的 JavaFX ListCell 的背景颜色

java - 在填充ObservableList时,是否必须从数据库中加载所有记录?

grails - 如何在 Grails 集成测试中部分模拟服务

java - Jar 找不到主类

java - 如何修复 Apache Ignite 中的 "Could not initialize class org.apache.ignite.IgniteJdbcThinDriver"错误?

java - 在两个不同的进程上运行两个 Activity

java - 如何在 Android 中一次又一次地从 wifi 列表中选择相同的 wifi 运营商?

grails - 想要删除和插入同一操作