Sagarmichael
Sagarmichael

Reputation: 1624

Grails Spock testing Controller and service

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

Answers (3)

RST
RST

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

dmahapatro
dmahapatro

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

pierrant
pierrant

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

Related Questions