2011-03-26 36 views
5

我有一个用于注册用户的命令对象,我想检查用户的年龄。该命令对象具有服务依赖关系。我如何测试我的dateOfBirth属性的自定义验证器?现在看起来直接来自文档,here单元测试依赖关系的命令对象的自定义验证程序

class RegisterUserCommand { 

    def someService 

    String username 
    String password 
    String password2 
    String email 
    Date dateOfBirth 

    static constraints = { 
    // other constraints 
    dateOfBirth blank: false, validator: {val, obj -> 
     return obj.someService.calculateAge(val) >= 18 
    } 
    } 

所以基本上问题是:我怎样才能模仿验证闭包的'obj'参数?

回答

8

在命令对象上测试验证的最简单方法是使用GrailsUnitTestCase.mockForConstraintsTests。模拟验证方法将应用于您的命令对象,您可以像在测试之外那样调用validate()

下面是如何编写单元测试的例子。约会对日期没有意义,所以我将它更改为nullable: false

import grails.test.GrailsUnitTestCase 

class RegisterUserCommandTests extends GrailsUnitTestCase { 
    RegisterUserCommand cmd 

    protected void setUp() { 
     super.setUp() 
     cmd = new RegisterUserCommand() 
     mockForConstraintsTests RegisterUserCommand, [cmd] 
    } 

    void testConstraintsNull() { 
     cmd.dateOfBirth = null 
     cmd.someService = [calculateAge: { dob -> 18 }] 
     def result = cmd.validate() 
     assert result == false 
     assert cmd.errors.getFieldErrors('dateOfBirth').code == ['nullable'] 
    } 

    void testConstraintsCustom() { 
     cmd.dateOfBirth = new Date() 
     cmd.someService = [calculateAge: { dob -> 17 }] 
     def result = cmd.validate() 
     assert result == false 
     assert cmd.errors.getFieldErrors('dateOfBirth').code == ['validator.invalid'] 
    } 
} 

请注意,您的服务将不会在单元测试注射(它会在虽然集成测试),所以你要么需要嘲笑它,如上,或创建一个实例并将其分配给cmd.someservice

+0

没有考虑模拟约束测试的命令对象:)它解决了这个问题。 – jjczopek 2011-03-27 10:20:26