测试命令对象验证

时间:2011-03-31 16:58:26

标签: unit-testing validation grails groovy

我有以下命令对象:

class CategoryCommand {

    String name
    String seoName

    static constraints = {
        name(blank: false)
        seoName(blank: false)
    }
}

我正在尝试使用此测试用例测试约束验证:

class ValidationTests extends ControllerUnitTestCase {


    protected void setUp() {
        super.setUp()
        mockCommandObject(CategoryCommand)
    }

    void testValidation() {
        def command = new CategoryCommand()
        assertFalse command.validate()
    }
}

但断言失败是因为命令对象通过验证,即使违反了约束。

我的猜测是,这不起作用,因为mockCommandObject添加了validate()方法,但此方法的实现始终返回true

还有其他方法可以测试命令类的验证。我需要validate()errors属性才能像运行应用程序时那样工作,以便正确测试它。我已经尝试将其作为集成和单元测试运行,但结果是一样的。

谢谢!

1 个答案:

答案 0 :(得分:0)

您应该在测试中使用mockCommandObject

mockCommandObject(CategoryCommand)

它允许您使用validate()方法并轻松访问errors属性。我为命令对象做了大量的单元测试,在我的情况下它运行得很好。

修改

我发现了一些奇怪的行为,基本上不知道为什么。我有一个命令对象:

class ChangePasswordCommand {
  String oldPassword
  String newPassword
  String newPassword2

  static constraints = {
    oldPassword(blank: false)
    newPassword(blank: false, matches: ConfigurationHolder.config.application.password.regex)
    newPassword2(blank: false, validator: { val, obj ->
      if (val != obj.newPassword) {
        return 'registration.password.mismatch.error'
      }
    })
  }
}

我也有测试(以及mockCommandObject(ChangePasswordCommand)方法setUp()):

    void testChangePasswordCommand_errors() {
            def cmd = new ChangePasswordCommand(oldPassword: '', newPassword: 'SomePass', newPassword2: 'SomeOtherPass')
            //def cmd = new ChangePasswordCommand()

            assertFalse cmd.validate()
            assertTrue cmd.hasErrors()
            assertEquals 3, cmd.errors.getErrorCount()
            assertEquals 'blank', cmd.errors.getFieldError('oldPassword').getCode()
            assertEquals 'matches.invalid', cmd.errors.getFieldError('newPassword').getCode()
            assertEquals 'registration.password.mismatch.error', cmd.errors.getFieldError('newPassword2').getCode()
}

当我进行测试时,它会通过。但是当我评论第一行并取消注释第二行时,为了将空命令对象置于测试中,测试在cmd.validate()断言时失败。此外,当我评论cmd.validate()断言时,它也无法断言cmd.hasErrors()。然后我删除了第一行中的oldPassword属性设置

def cmd = new ChangePasswordCommand(newPassword: 'SomePass', newPassword2: 'SomeOtherPass')

并且测试也失败了。所以看起来它因为null属性值而制动。我无法解释这一点。

编辑2

我是瞎子什么的。 mockCommandObject添加validate()方法,但不添加hasErrors()方法。在我的测试中,setUp()我也有:

ChangePasswordCommand.metaClass.hasErrors() { !delegate.validate() }