[英]How can I mock a grails 4 service in a controller unit test
I don't understand how mocking works in Grails 4.0.我不明白在 Grails 4.0 中模拟是如何工作的。 I have this unit test that fails (it is just an illustration of the real test, the real test actually involves the 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"]]
}
with error有错误
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)
and stdout和标准输出
null
The interesting thing is that this works fine if I use a very simple test class instead of MySearchService .有趣的是,如果我使用一个非常简单的测试类而不是 MySearchService ,这可以正常工作。 So I am assuming that it has to do something with the way Grails/Spring is setup.
所以我假设它必须与 Grails/Spring 的设置方式有关。 This might also explain the lines:
这也可以解释以下几行:
Unmatched invocations (ordered by similarity):
1 * mock.invokeMethod('find', [<java.lang.String@0 value= hash=0>])
But how do I set it up otherwise?但是我该如何设置呢? I can't find this anywhere in the documentation.
我在文档中的任何地方都找不到这个。 Thanks for any help!
谢谢你的帮助!
Similar question (without answer): How to partially mock service in Grails integration test类似问题(无答案): 如何在 Grails 集成测试中部分模拟服务
The syntax for your mock is incorrect - here's a working example tested in Grails 4.0.1您的模拟的语法不正确 - 这是在 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']
}
See - http://spockframework.org/spock/docs/1.0/interaction_based_testing.html - Section: Declaring Interactions at Mock Creation Time
请参阅 - http://spockframework.org/spock/docs/1.0/interaction_based_testing.html - 部分:
Declaring Interactions at Mock Creation Time
Note this is likely not in the Grails docs as there is nothing Grails specific about it - just Spock.请注意,这可能不在 Grails 文档中,因为没有任何特定于 Grails 的内容 - 只是 Spock。
here is already a workaround that is not great:这里已经有一个不太好的解决方法:
void "test listSources"() {
given:
def mock = Mock(MySearchService) {
invokeMethod('find', _) >> [["label": "abc", "description": "xsad"]]
}
when:
System.out.println(mock.find(''))
then:
1 * mock.invokeMethod('find', _) >> [["label": "abc", "description": "xsad"]]
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.