在Grails 2.2.1中模拟公式派生的字段

时间:2015-08-26 15:35:06

标签: unit-testing grails mocking spock

我有一个Domain类,它使用带公式的约束来计算几个字段。这些字段是可空的,但是当我进行单元测试时,创建的对象无法保存,抛出ValidationException。

当我在运行调试器时测试相同的代码(不在单元测试中)时,字段为空,但没有错误。

我觉得如果我可以将公式模拟为0,我就可以成功运行测试。例如:Part.metaClass.getNumberOfObj1 = { return 0 }。当然,这不起作用。

有没有办法模拟公式到这些字段的映射,以便可以保持对象?或者,如果没有,有没有办法修改我的设置,以消除我得到的(奇怪的)错误?

域类

class Part extends Base {
    ...
    Long    numberOfObj1
    Long    numberOfObj2
    Long    numberOfObj3

    static hasMany = [obj1:Obj1,obj2:Obj2,obj3:Obj3]

    static mapping = {
        numberOfObj1  formula: '(select count(id) from ' + Base.defaultSchema() + '.obj_1 ob1 where (ob1.pt_id = ID and ob1.deleted = \'F\'))'
        numberOfObj2  formula: '(select count(id) from ' + Base.defaultSchema() + '.obj_2 ob2 where (ob2.pt_id = ID)'
        numberOfObj3  formula: '(select count(id) from ' + Base.defaultSchema() + '.obj_3 ob1 where (ob3.pt_id = ID )'  
    ... }  
}

单元测试

@TestMixin(ControllerUnitTestMixin)
@TestFor(PartController)
class PartControllerSpec extends BaseTestSpec {
    def "given a part search, when the create action is called"() {
        given:
            def obj1= createObj1()
            params.number = "1"
            params.rev = "A"

        when:
            controller.create()

        then:
            //test stuff
    }
}

在controller.create()内部

def create() {
    newPart = new Part(number:params.number,
                       revision:params.rev)//fields are null here
    try{
        newPart.save(flush:true, failOnError:true)
    } catch (Throwable th) {
        return
    }

错误

grails.validation.ValidationException: Validation error occured during call to save():
- Field error in object 'com.Part' on field 'numberOfObj1': rejected value [null];codes [com.Part.numberOfObj1.nullable.error.com.Part.numberOfObj1,...

2 个答案:

答案 0 :(得分:1)

您可以在此字段中添加nullable: true约束。这就是我的所作所为。

另见Grails3 unit test for domain class with derived property

答案 1 :(得分:0)

以下

提供了更好的解决方案
static constraints = {
    if (Environment.current == Environment.TEST) {
        derivedField(nullable: true)
    }
}

这样您就不必处理Derived properties may not be constrained启动警告