Grails 2.4.4生成的控制器测试失败

时间:2015-06-05 00:30:06

标签: unit-testing grails

我测试了控制器的保存操作。它只是用正确的参数执行动作,但问题出在redirectedUrl行:它为null。

使用该应用程序,在保存域实例后,我将重定向到show动作并正确显示show视图。

这里有什么问题的线索?

控制器:

@Transactional(readOnly = true)
class FolderController {

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

    @Transactional
    def save(Folder folderInstance) {

        if (folderInstance == null) {
            notFound()
            return
        }

        if (folderInstance.ehrId)
        {
           def ehr = ehr.Ehr.get(folderInstance.ehrId)
           ehr.directory = folderInstance
           ehr.save() 
        }

        if (folderInstance.hasErrors()) {
            respond folderInstance.errors, view:'create'
            return
        }

        folderInstance.save flush:true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [message(code: 'folder.label', default: 'Folder'), folderInstance.id])
                redirect folderInstance
            }
            '*' { respond folderInstance, [status: CREATED] }
        }
    }
    ...
}

测试:

@TestFor(FolderController)
@Mock(Folder)
class FolderControllerSpec extends Specification {

        ...
    void "Test the save action correctly persists an instance"() {

        when:"The save action is executed with a valid instance"
            response.reset()
            populateValidParams(params)
            def folder = new Folder(params)

            controller.save(folder)
            println folder.errors // no errors

        then:"A redirect is issued to the show action"
            response.redirectedUrl == '/folder/show/1'
            controller.flash.message != null
            Folder.count() == 1
    }
    ...
}

输出:

junit.framework.AssertionFailedError: Condition not satisfied:

response.redirectedUrl == '/folder/show/1'
|        |             |
|        null          false
org.codehaus.groovy.grails.plugins.testing.GrailsMockHttpServletResponse@112b2f1

    at directory.FolderControllerSpec.Test the save action correctly persists an instance(FolderControllerSpec.groovy:61)

2 个答案:

答案 0 :(得分:1)

Grails scaffold 控制器是更智能的控制器。他们尊重请求格式并相应地生成响应。

例如,您的保存操作 - 如果请求格式为form,则会重定向到show操作,否则会返回状态为CREATED的已保存域实例。

以下代码负责此

request.withFormat {
    form multipartForm {
        flash.message = message(code: 'default.created.message', args: [message(code: 'folder.label', default: 'Folder'), folderInstance.id])
        redirect folderInstance
    }
    '*' { respond folderInstance, [status: CREATED] }
}

在您的测试用例中,您的请求不属于form类型,因此redirectedUrl为空。

要发出form请求,请在进行保存调用之前在测试用例中添加以下代码 -

request.format = 'form'

希望这有帮助。

答案 1 :(得分:1)

我忘了添加allowedMethods字段。

第一个问题是生成的测试没有为相应的动作设置正确的请求方法,因此需要调用.save():controller.request.method =“POST”

那么@ user1690588建议的内容(request.format ='form')就可以获得正确的redirectedUrl。

我的最终测试如下:

RunWorkCompleted