I have a controller like this:
class NotificationApiController {
def countService
def getCount() {
def results = countService.getCount()
render results as JSON
}
}
And the controller test like this:
Closure doWithSpring() {{ ->
countService(CountService)
}}
CountService countService
def setup() {
}
def cleanup() {
}
void "test getCount method"() {
given:
def countService = Mock(CountService) {
1 * getCount(_) >> [count: 2]
}
when:
def y = controller.getCount()
then:
y == [count: 2]
}
It appears it always calls into the actual CountService injected in Closure doWithSpring(), not my mock countService, but without the definition of Closure doWithSpring()..., I will get this error
Cannot invoke method getCount() on null object
java.lang.NullPointerException: Cannot invoke method getCount() on null object
The documentation on unit testing in 4.0 is really limited and I am not exactly sure how should I do this. I see some samples in Grails 2.3 or 3.3. version, but they all seems not working for me, mostly due to the difference of Spock and Mixin framework I guess. Any suggestions on how to do this?
You have omitted some details that might affect the recommendation but the project at https://github.com/jeffbrown/chrisjiunittest shows 1 way to go about this.
package chrisjiunittest
import grails.testing.web.controllers.ControllerUnitTest
import spock.lang.Specification
class NotificationApiControllerSpec extends Specification implements ControllerUnitTest<NotificationApiController> {
void "test something"() {
setup:
// whether or not this is the right thing to do
// depends on some other factors, but this is
// an example of one approach...
controller.countService = Mock(CountService) {
getCount() >> [count: 2]
}
when:
controller.getCount()
then:
response.json == [count: 2]
}
}
Another option:
package chrisjiunittest
import grails.testing.web.controllers.ControllerUnitTest
import spock.lang.Specification
class NotificationApiControllerSpec extends Specification implements ControllerUnitTest<NotificationApiController> {
Closure doWithSpring() {
// whether or not this is the right thing to do
// depends on some other factors, but this is
// an example of one approach...
{ ->
countService MockCountService
}
}
void "test something"() {
when:
controller.getCount()
then:
response.json == [count: 2]
}
}
class MockCountService {
Map getCount() {
[count: 2]
}
}