Grails 2+ (im Moment 2.3) und Unit Tests mit Controllern, die chain() benutzen

Beim Ausprobieren der neuen Version 2.3 des Grails-Frameworks bin ich auf das Problem gestoßen, dass seit Version 2.0 chainArgs in Unit-Tests nicht mehr unterstützt werden. Mann kann zwar immer noch Controller mit chain() testen und es ist eigentlich sogar intuitiver, aber leider nirgendwo so recht dokumentiert. Zumindest konnte ich keine Doku finden...

Die chain action findet man in response.redirectUrl und das chainModel in controller.chainModel

Beispiel mit Spock (default seit Grails 2.3)

class FooController {

    def springSecurityService

    def register(RegisterCommand rc) {
        User currentUser = springSecurityService.currentUser as User
        if (springSecurityService.loggedIn && currentUser) {
            flash.error = message(code: "error.register-while-already-logged-in")
            redirect action: "show", params: [id: currentUser.id]
        } else {
            if (request.method == 'POST') {
                chain action: "handleRegisterForm", model: [rc: rc]
            } else
                [rc: new RegisterCommand()]
        }
    }

    def handleRegisterForm(RegisterCommand rc) {
        render "Not yet implemented"
    }
}

 

Und der Test geht dann:

@TestFor(FooController)
@Mock([User])
@Stepwise
class FooControllerUnitSpec extends Specification {

    RegisterCommand rc
    User testUser
    SpringSecurityService springSecurityService = Mock(SpringSecurityService)

    def setup() {
        //create a valid RegisterCommand
        rc = mockCommandObject(RegisterCommand) as RegisterCommand
        rc.username = "TestUser"
        rc.email = "test@test.com"
        rc.emailCheck = "test@test.com"
        rc.password = "1Ijd_dheIp"
        rc.passwordCheck = "1Ijd_dheIp"
        rc.receiveEmail = true
        rc.acceptTOS = true

        User.metaClass.encodePassword = {-> } // necessary because of the methods in the User class

        testUser = new User(
                username: "Test",
                email: "test@test.de",
                password: "passwd222",
                enabled: true
        ).save()

        controller.springSecurityService = springSecurityService
    }

    def cleanup() {
    }

    void "valid post requests to register() should be chained to handleRegisterForm()"() {
        when:
        request.method = 'POST'
        controller.register(rc)
        then:
        1 * springSecurityService.getCurrentUser() >> null
        1 * springSecurityService.isLoggedIn() >> false
        response.redirectedUrl== '/account/handleRegisterForm' && controller.chainModel.rc
    }
}
Share/Save