【问题标题】:mocking formula-derived fields in Grails 2.2.1在 Grails 2.2.1 中模拟公式派生字段
【发布时间】:2015-08-26 15:35:06
【问题描述】:

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

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

我觉得如果我可以 Mock 公式返回 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,...

【问题讨论】:

  • 为什么不只是集成测试?
  • @JamesKleeh 是的,这始终是一个选项,但我们希望在 Int 测试上创建单元测试以节省测试时间。由于单元测试运行得更快。另外,我想我只是痴迷于让它发挥作用:)

标签: unit-testing grails mocking spock


【解决方案1】:

您可以向该字段添加nullable: true 约束。这就是我所做的。

另见Grails3 unit test for domain class with derived property

【讨论】:

    【解决方案2】:

    以下是更好的解决方案

    static constraints = {
        if (Environment.current == Environment.TEST) {
            derivedField(nullable: true)
        }
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-13
      • 1970-01-01
      • 1970-01-01
      • 2022-10-17
      相关资源
      最近更新 更多