【问题标题】:Grails 2.4.4 generated controller test failsGrails 2.4.4 生成的控制器测试失败
【发布时间】:2015-06-06 14:56:10
【问题描述】:

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

使用该应用程序,在保存域实例后,我获得了对显示操作的重定向,并且显示视图正确呈现。

这里有什么问题的线索吗?

控制器:

@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)

【问题讨论】:

    标签: unit-testing grails


    【解决方案1】:

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

    例如您的保存操作——如果请求格式为form,它将重定向到显示操作,否则返回状态为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'
    

    希望这会有所帮助。

    【讨论】:

    • 正在审查代码,这不是脚手架控制器,因为它没有脚手架属性:grails.github.io/grails-doc/2.4.4/ref/Command%20Line/…。最初的问题是 Grails 没有在测试中生成正确的请求方法,当我修复它时,你对格式的建议就成功了。我希望 Grails 能够在测试中生成正确的请求方法和格式,但是在生成之后,它仍然需要一些手动工作。
    【解决方案2】:

    我忘了添加 allowedMethods 字段。

    第一个问题是生成的测试没有为对应的操作设置正确的请求方法,所以调用 .save() 需要这样做:controller.request.method = "POST"

    然后@user1690588 的建议 (request.format = 'form') 成功获得了正确的 redirectedUrl。

    我的最终测试如下所示:

    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.request.method = "POST"
            request.format = 'form'
    
            controller.save(folder)
    
        then:"A redirect is issued to the show action"
            response.redirectedUrl == '/folder/show/1'
            controller.flash.message != null
            Folder.count() == 1
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 2013-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多