Grails Controller integration test executes actions of the parent, RestfulController class

68 Views Asked by At

I have a weird problem with integration testing restful controllers... In the following code snippet, when I make a post request from tests, the save method of the parent, RestfulController class is called instead of the save method of the child class, MyController and because they have different signatures, this ends up resulting in a UNPROCESSIBLE_ENTITY response.

class MyController extends RestfulController<MyDomain> {
    static responseFormats = ['json', 'xml', 'hal']

    MyController() {
        super(MyDomain)
    }


    def save(MyCommand command) {
        ...
    }
}

When I run the following test, the save() action of my controller's parent class, RestfulController gets executed, thus leading to UNPROCESSIBLE_ENTITY response, since I am using a Command object which is different from my domain class.

void "Test the save action correctly persists an instance"() {
        when: "The save action is executed with valid data"

        response = restBuilder.post(resourcePath) {
            accept('application/json')
            header('Authorization', "Bearer ${accessToken}")
            json validJson
        }

        then: "The response is correct"

        response.status == CREATED.value()
        response.json.id
        Vote.count() == 1
    }

What can I do to fix this, please?

1

There are 1 best solutions below

3
Jeff Scott Brown On

Overloading controller actions is not supported. You can override them, but you can't overload them.

What is happening is the framework is invoking the no-arg save() action in the parent class, which never invokes your method (nor should it).

You can rename your save(MyCommand command) so it doesn't have the same name as an action in your parent class and then provide a corresponding URL mapping and you will be on your way. Depending on what you want to do in the action, that may or may not be the best thing, but that is 1 path you can take.

I hope that makes sense.