0
votes

I have a test for a PersonController, it just executes save() with no params, so an invalid person is created. It should return the invalid person in the model and show the create view. But the model is empty.

The test:

import org.junit.*
import grails.test.mixin.*

@TestFor(PersonController)
@Mock(Person)
class PersonControllerTests {
   ...
   void testSave() {
       controller.save() // creates invalid person, redirects to create
       assert model.personInstance != null
       assert view == '/person/create'

       response.reset()

       populateValidParams(params)
       controller.save()

       assert response.redirectedUrl == '/person/show/1'
       assert controller.flash.message != null
       assert Person.count() == 1
   }
   ...
}

The controller:

class PersonController {

   ...
    def save() {
        def personInstance = new Person(params)
        if (!personInstance.save(flush: true)) {
            render(view: "create", model: [personInstance: personInstance])
            return
        }

        flash.message = message(code: 'default.created.message', args: [message(code: 'person.label', default: 'Person'), personInstance.id])
        redirect(action: "show", id: personInstance.id)
    }
   ...
}

The output:

junit.framework.AssertionFailedError: Assertion failed: 

assert model.personInstance != null
       |     |              |
       [:]   null           false

    at demographic.PersonControllerTests.testSave(PersonControllerTests.groovy:43)

How can I get the right model?

Is this the expected behavior or is this a Grails bug?

1
I'm not certain that this is your problem, and without seeing the full definition of PersonController, but have you tried setting controller.request.method = 'POST' in the test (before controller.save())? - Jon Burgess
I was able to check this by tracking you down the code on github :-) - Jon Burgess

1 Answers

1
votes

The test is failing (rightly so, I believe) because of the HTTP method restrictions in the controller, i.e. the line:

static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

Set the HTTP method in the test, and the test passes:

void testSave() {
    controller.request.method = 'POST'
    controller.save() // creates invalid person, redirects to create
    ...