register
other register

Thursday, November 25, 2010

Mocking Command Object in Grails

Class PersonCommand {
  String firstname
  String lastname

  static constraints = {
    firstname(blank: false)
    lastname(blank: false)
  }
}

Class PersonController {
  def save {PersonCommand cmd ->
    if (cmd.hasErrors()) {
      ...
    }
    else {
      render (view: 'confirm', model: [person: cmd])
    }
  }
}

Create an instance of that command object and pass it to the action. Below also shows the way to pass on a map of parameters to construct the command object. This needs the help of the metaClass.

import grails.plugin.spock.ControllerSpec

Class PersonControllerSpec extends ControllerSpec {
  def 'save action' () {
    given "":
    mockCommandObject(PersonCommand)
    Map mp = [firstname: 'joe', lastname: 'blog']
    controller.metaClass.getParams { -> mp}

    when : "person form parameters are submitted"
    // This works
    // def cmd = new PersonCommand(firstname: 'joe', lastname: 'blog')

    // This works better as it allows to pass on a map of parameters
    def cmd = new PersonCommand(mp)

    // Call the action
    controller.save(cmd)

    then : "the command object should be valid"
    assert cmd.valid()

    and : "the right model and view can be retrieved"
    renderArgs.view = 'confirm'
    renderArgs.model.person.firstname == 'joe'
  }
}

Note that the mockCommandObject only works when doing controller unit test, not domain unit test.

No comments: