unit-testinggrailsgroovygmock

Testing a Grails controller using a mock service with GMock (0.8.0)


I have a grails 2.1 app which has a controller that calls a method on a service, passing in a request and a response:

class FooController {
    def myService
    def anAction() {
        response.setContentType('text/xml')
        myservice.service(request,response)
}

I want to unit test this method. And I want to do so using GMock (version 0.8.0), so this is what I tried:

def testAnAction() {
    controller.myService = mock() {
        service(request,response).returns(true)
    }
    play {
        assertTrue controller.anAction()
    }
}

Now this fails saying that that it failed expectations for request.

Missing property expectation for 'request' on 'Mock for MyService'

However, if I write my test like this:

def testAnAction() {
    def mockService = mock()
    mockService.service(request,response).returns(true)
    controller.myService = mockService
    play {
        assertTrue controller.anAction()
    }
}

The test will pass fine. As far as I am aware they are both valid uses of the GMock syntax, so why does the first one fail and the second one not?

Cheers,


Solution

  • I assume you write your tests in a test class FooControllerTest generated by grails.

    In a such way, FooControllerTest class is annoted by @TestFor(FooController) wich inject some usefull attributes.

    So request is an attribute of your test class, not a variable in the local scope.

    It's why it is not reachable from a internal Closure.

    I'm convinced that following code could work (I have not tested yet) :

    def testAnAction() {
        def currentRequest = request
        def currentResponse = response
        controller.myService = mock() {
            service(currentRequest,currentResponse).returns(true)
        }
        play {
           assertTrue controller.anAction()
        }
    }