Grails 1.3.5 controller test nulls命令对象

直接从“Grails的权威指南(第二版)”第104页开始:
void testLoginUserNotFound() {
    mockRequest.method = "POST"
    mockDomain(User)
    MockUtils.prepareForConstraintsTests(LoginCommand)
    def cmd = new LoginCommand(login:"fred", password:"letmein")

    cmd.validate()
    controller.login(cmd)

    assertTrue cmd.hasErrors()
    assertEquals "user.not.found", cmd.errors.login
    assertEquals "/store/index", renderArgs.view
}
运行此测试时,它将失败:
junit.framework.AssertionFailedError: junit.framework.AssertionFailedError: null
...我追踪到的“cmd”引用在该点为null。在调用action.login之前,cmd有效并填充,之后为null。 如何测试命令对象?     
已邀请:
cmd
不是
null
;然而,
assertTrue
null
信息抛出
AssertionFailedError
。提供默认消息(
assertTrue "default message", cmd.hasErrors()
)或仅提供状态,
assert cmd.hasErrors()
。 那么,让我们看看为什么
cmd.hasErrors()
返回
false
。 - 那是因为自定义验证器没有返回
false
,而是一些字符串,根据“Groovy Truth”评估为
true
。 (在那里,自本书出版以来,Grails API似乎已经发生了变化。) 在
LoginCommand
班,改变
login blank:false, validator:{ val, cmd ->
    if(!cmd.user)
        return "user.not.found"
}
login blank:false, validator:{ val, cmd ->
    if(!cmd.user)
        return false
}
然后,错误代码将是“LoginCommand.login.validator”。 如果您需要自定义错误代码,您可以自己添加错误对象(不返回任何内容),如下所示:
login blank:false, validator:{ val, cmd ->
    if(!cmd.user)
        cmd.errors.rejectValue('login', 'user.not.found')
}
P.S。:你不应该直接使用
MockUtils
类,而是使用
extend GrailsUnitTest
。此外,
MockUtils.prepareForConstraintsTests(Class)
已被弃用;而且,它不适合命令对象。 - 使用
mockForConstraintsTests(Class)
方法,继承自
GrailsUnitTest
。     
我在控制器单元测试中使用此方法为命令对象添加额外的管道:
  private def invoke(String action) {
    def types = controller."$action".parameterTypes
    if (types && types.length == 1) {
      Class cmdClass = types[0]
      mockCommandObject(cmdClass)
      def cmd = cmdClass.newInstance()
      controller.params.each{ key, value ->
        try{ cmd."$key" = value } catch(MissingPropertyException ex){}
      }
      cmd.validate()
      controller."$action"(cmd)
    } else {
      controller."$action"()
    }
  }
测试看起来像这样:
    setup:
    controller.params.contractNum = "invalid"


    when:
    invoke "lookup"
    

要回复问题请先登录注册