在我的JavaFX应用程序中,我正在使用Spock和Groovy进行测试。我一直致力于WebBrowserController照顾我的JavafX WebView组件。我想测试一些功能,这些功能取决于的当前位置和文档WebView。
WebBrowserController
WebView
WebBrowserController的相关部分:
public WebEngine getEngine() { return panel.getWebView().getEngine(); }
这就是我WebBrowserController为测试创建实例的方式。请注意,GroovyMock我在这里使用的- 普通语言Mock(...)不适用于最终课程,WebEngine而是最终课程。
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,而且使用介于两者之间的包装值)。
getMockedControllerWithDocument
getLocation()
总结:为什么完全相同的对象在行为上会因调用方法的位置不同而不同?
因为GroovyMock,GroovySpy并且GroovyStub仅对Groovy类起作用。当被Java类调用时,它们的行为类似于普通的Spock模拟。这是记录在这里:
GroovySpy
GroovyStub
小费 什么时候应该把Groovy的嘲弄胜过常规的嘲弄?当规范下的代码用Groovy编写并且需要某些独特的Groovy模拟功能时,应使用Groovy模拟。 当从Java代码调用时,Groovy模拟将表现得像常规模拟一样。 请注意,仅因为规范和/或模拟类型下的代码是用Groovy编写的,所以不必使用Groovy模拟。除非有具体的理由使用Groovy模拟,否则最好选择常规模拟。
什么时候应该把Groovy的嘲弄胜过常规的嘲弄?当规范下的代码用Groovy编写并且需要某些独特的Groovy模拟功能时,应使用Groovy模拟。 当从Java代码调用时,Groovy模拟将表现得像常规模拟一样。 请注意,仅因为规范和/或模拟类型下的代码是用Groovy编写的,所以不必使用Groovy模拟。除非有具体的理由使用Groovy模拟,否则最好选择常规模拟。