我不明白 Grails 4.0 中的模拟是如何工作的。 我的这个单元测试失败了(这只是真实测试的一个说明,真实测试实际上涉及 Controller ):
import com.myapp.MySearchService
class ApiControllerSpec extends Specification implements ControllerUnitTest<ApiController> {
def setup() {
}
def cleanup() {
}
void "test listSources"() {
given:
def mock = Mock(MySearchService) {
find(_) >> [["label": "abc", "description": "xsad"]]
}
when:
System.out.println(mock.find(''))
then:
1 * mock.find(_) >> [["label": "abc", "description": "xsad"]]
}
有错误
Too few invocations for:
1 * mock.find(_) >> [["label": "abc", "description": "xsad"]] (0 invocations)
Unmatched invocations (ordered by similarity):
1 * mock.invokeMethod('find', [<java.lang.String@0 value= hash=0>])
at org.spockframework.mock.runtime.InteractionScope.verifyInteractions(InteractionScope.java:93)
at org.spockframework.mock.runtime.MockController.leaveScope(MockController.java:77)
at toe.ApiControllerSpec.test listSources(ApiControllerSpec.groovy:29)
和标准输出
null
有趣的是,如果我使用一个非常简单的测试类而不是 MySearchService,则效果很好。所以我假设它必须与 Grails/Spring 的设置方式有关。这也可以解释这些行:
Unmatched invocations (ordered by similarity):
1 * mock.invokeMethod('find', [<java.lang.String@0 value= hash=0>])
但是我该如何设置呢?我在文档中找不到这个。感谢您的帮助!
类似问题(没有答案): How to partially mock service in Grails integration test
最佳答案
您的模拟语法不正确 - 这是在 Grails 4.0.1 中测试的工作示例
void "test something"() {
given:
def mock = Mock(SearchService) {
1 * find(_) >> ['foobar'] // note the interaction count is required when defining this way.
}
when:
def result = mock.find('')
then:
result == ['foobar']
}
参见 - http://spockframework.org/spock/docs/1.0/interaction_based_testing.html - 部分:在模拟创建时声明交互
请注意,这可能不在 Grails 文档中,因为 Grails 没有任何具体内容 - 只有 Spock。
关于spring - 如何在 Controller 单元测试中模拟 grails 4 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59030447/