[英]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,它在中间使用了一个包装值) .
总结一下:为什么完全相同的对象会根据调用其方法的位置而表现不同?
因为GroovyMock
、 GroovySpy
和GroovyStub
只能按您对 Groovy 类的预期工作。 当被 Java 类调用时,它们的行为就像普通的 Spock 模拟。 这是记录在这里:
提示
Groovy Mock 什么时候应该比普通 Mock 更受欢迎? 当规范下的代码是用 Groovy 编写的并且需要一些独特的 Groovy 模拟功能时,应该使用 Groovy 模拟。 当从 Java 代码调用时,Groovy 模拟将表现得像常规模拟。 请注意,没有必要仅仅因为规范和/或模拟类型下的代码是用 Groovy 编写的就使用 Groovy 模拟。 除非您有使用 Groovy 模拟的具体理由,否则更喜欢常规模拟。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.