Reputation: 1624
Hi I have a controller called ApiController which uses a service called ApiService like so:
def createCategory(){
def jsonObj = request.JSON
jsonObj.each{ key, value ->
params.put(key,value)
}
render apiService.createCategory(params)
}
Which works fine. But I cannot seem to write a test for it.
This is how far I have got:
@TestFor(ApiController)
@Mock([Category,ApiService])
class CategorySpec extends Specification {
def setup() {
}
def cleanup() {
}
void "test"() {
setup:
def apiService = Mock(ApiService)
when:
request.method = 'POST'
request.requestMethod = 'POST'
params.categoryID = 'test'
controller.createCategory()
then:
println(response)
1==1
}
From this I get the following error:
java.lang.NullPointerException: Cannot invoke method createCategory() on null object
This is obviously because It cannot see my apiService bean. So My question is how do i do this in Spock?
Upvotes: 5
Views: 3732
Reputation: 602
It's most likely to do with the Transactional bug
: https://github.com/grails/grails-core/issues/1501
ApiService apiService = new ApiService()
controller.apiService = apiService
apiService.transactionManager = Mock(PlatformTransactionManager) { getTransaction(_) >> Mock(TransactionStatus) }
This is a temporary fix (as per the bug report comment) ... this has worked for me :)
Upvotes: 7
Reputation: 50245
ApiService
is mocked sucessfully in the test but how are you providing the mock to the controller? Unit specs are deprived of DI, you cannot expect it to autowire. Therefore,
setup:
controller.apiService = Mock(ApiService)
Upvotes: 0
Reputation: 320
This is how I would do it in Grails 2.4, without annotation @Mock
on the spec class:
when:
def serviceMock = mockFor(ApiService)
serviceMock.demand.createCategory { def params -> "output sample" }
controller.apiService = serviceMock.createMock()
controller.createCategory()
Upvotes: 1