当前位置: 首页 > 知识库问答 >
问题:

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

董弘新
2023-03-14

在我的JavaFX应用程序中,我使用Spock和Groovy进行测试。我有专门的WebBrowserController来处理我的JavafXWebView组件。我想测试一些依赖于WebView当前位置和文档的功能

WebBrowserController的相关部分:

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

这就是我为测试创建WebBrowserController实例的方法。注意我在这里使用的groovymock-普通mock(...)不适用于final类,而webengine是final类。

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

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

共有1个答案

刘俊语
2023-03-14

因为groovymockgroovyspygroovystub只能像您所期望的那样工作于Groovy类。当被Java类调用时,它们的行为就像普通的Spock模拟一样。这里对此进行了记录:

什么时候Groovy模拟应该比常规模拟更受青睐?当规范中的代码是用Groovy编写的,并且需要一些独特的Groovy mock特性时,应该使用Groovy mock。当从Java代码调用时,Groovy mocks的行为与常规mocks类似。注意,仅仅因为规范和/或模拟类型下的代码是用Groovy编写的,所以没有必要使用Groovy模拟。除非您有具体的理由使用Groovy mock,否则最好使用常规mock。

 类似资料:
  • 问题内容: 在我的JavaFX应用程序中,我正在使用Spock和Groovy进行测试。我一直致力于照顾我的JavafX 组件。我想测试一些功能,这些功能取决于的当前位置和文档。 WebBrowserController的相关部分: 这就是我为测试创建实例的方式。请注意,我在这里使用的- 普通语言不适用于最终课程,而是最终课程。 下面的行正在测试中,并且中断。我希望返回“一些随机字符串”,但我只是通

  • Spock对存根和模拟做了很强的区分。当要更改的内容从被测试类使用的类返回时,请使用存根,这样您就可以测试if语句的另一个分支。使用mock,当您不关心测试中的类返回什么时,只需调用另一个类的另一个方法,并且您希望确保调用了该方法。很整洁。然而,假设您有一个具有流利API的构建器,它使人们。您希望测试调用此生成器的方法。 所以最初,我想只是模拟构建器,然后myMethod()的单元测试应该检查具有

  • 在运行spock测试时,我需要帮助模拟一个类及其从yaml文件获得的数据。我有一个用groovy编写的microservice,它根据yaml文件中的字段名参数进行字段映射。 我有一个projectProperties类,它从yaml文件中提取数据。 这个类将从 /src/main/resourcesapplication.yaml文件中提取变量值 当我运行spock测试时,它无法从project

  • 我有一个在kotlin的‘基地’项目配置与gradle DSL。在基我有模块'app'和模块'library'。模块应用程序使用模块库。我想从模块应用程序的测试(准确地说是库的testUtils包)访问模块库的测试。 我还检查了代码所在的问题: 我需要在库的源代码中添加,这样在应用程序的测试中,我就可以使用库的测试包,而在应用程序的源代码中,我就不能使用库的测试了。 谢谢你。

  • 我用代码编写了以下旧方法,用于访问服务类中的请求对象,例如:

  • 注意:如果我不使用JMockit,我可以进行调试,但是在生产代码中测试方法需要使用这个方法。 关于如何让调试器从使用JMockit的Spock测试中停在Java代码中,有什么想法吗?