Testing Grails controller actions that use bindData method and render validation errors as JSON

Let’s assume that we have a controller action in a grails application that updates a user domain instance. We want name and surname to be updateable but login and password shouldn’t be updateble. To achieve that we will use the controller’s bindData() method with whitelisting. The action will be called using ajax so we also want to render JSON with validation errors in response if there were any. So our controller might look like that:

And the example User class might look like that:

Our next step will be unit testing the action. We want to make sure that only the whitelisted fields are copied from parameters (testUpdate) and also that the validation errors are rendered (testUpdateValidationError):

It turns out that those tests won’t pass. But not because of the fact that we have bugs in the code, it’s just that grails doesn’t do enough magic for our controller action to be unit testable out of the box.

First problem is that the bindData() method is not mocked in ControllerUnitTestCase. Fortunately thanks to this stackoverflow response we know how to easily mock it. To make it reusable let’s create a mixin out of it:

Now all that we have to do to make it work is to apply it on our test class and call the mockBindData() method in the setUp() method.

Second problem is that by default the JSON converter doesn’t know how to convert bean validation errors. But that’s easily fixable as well – all we have to do is register validation error marshaller in the testUpdateValidationError test:

After the aforementioned changes our passing test class should look like that:

4 replies
  1. Søren Berg Glasius
    Søren Berg Glasius says:

    Hi Marcin,

    That is a very cool tip! And if you replace @Category(ControllerUnitTestCase) with @Category(ControllerSpec) you can use in your Spock tests.

    Best regards,
    Søren Berg Glasius

Trackbacks & Pingbacks

  1. […] Probando acciones de controladotes grails que usan métodos bindData y renderizan errores de validac… […]

  2. […] Testing grails controller actions that use bindData method and render validation errors as JSON […]

Comments are closed.