问题
I am attempting to write a test for a controller which calls a service method. I would like to mock a dependent method within that service.
My spec is as follows:
MyController myController = new MyController()
def mockMyService
def "My spy should be called"() {
when:
mockMyService = Spy(MyService) {
methodToSpy() >> {
println "methodToSpy called"
} // stub out content of this fn
}
myController.myService = mockMyService
myController.callService()
then:
1 * mockMyService.methodToSpy()
}
When I attempt to run this test, I get the following error:
Failure: | My spy should be called(spybug.MyControllerSpec) | Too few invocations for: 1 * mockMyService.methodToSpy() (0 invocations) Unmatched invocations (ordered by similarity): 1 * mockMyService.serviceMethod() 1 * mockMyService.invokeMethod('methodToSpy', []) 1 * mockMyService.invokeMethod('println', ['in serviceMethod about to call methodToSpy']) 1 * mockMyService.invokeMethod('println', ['Back from methodToSpy'])
As you can see, Spock is capturing the Groovy invokeMethod call, not the subsequent call to the actual method. Why is this happening?
The complete project is available here.
回答1:
Try this:
def "My spy should be called"() {
given:
mockMyService = Mock(MyService)
myController.myService = mockMyService
when:
myController.callService()
then:
1 * mockMyService.methodToSpy(_) >> { println "methodToSpy called" }
}
According to the spock documentation for stubs, if you want to use the cardinality, you must use a Mock and not a Stub.
http://spockframework.github.io/spock/docs/1.0/interaction_based_testing.html#_stubbing
来源:https://stackoverflow.com/questions/32104348/how-to-partially-mock-service-in-grails-integration-test