Grails:如何使用spock进行单元测试时如何为瞬态场保存价值?

roe*_*gol 3 grails groovy unit-testing transactions spock

为了测试具有瞬态字段的域类,我尝试通过以下两种方式为该字段设置值:

Requirement requirement = new Requirement(linearProduct: linearProduct, periodIndexes: [1,2,3])
requirement.periodIndexes = [1,2,3]
Run Code Online (Sandbox Code Playgroud)

当进入测试函数时,它们都使该字段显示为空对象.

我的问题是如何使值通过,虽然它是瞬态场?

Jef*_*own 6

瞬态属性是bindable:false默认的.如果您希望periodIndexes字段可以与命名参数绑定,则必须明确说明:

class Requirement {
    transient List periodIndexes

    static constraints = {
        periodIndexes bindable: true
    }
}
Run Code Online (Sandbox Code Playgroud)

目前尚不清楚为什么你的requirement.periodIndexes = [1,2,3]结果为null.它不应该.如果您可以展示更完整的测试,我可以帮助您.

编辑:

举个例子...

域类:

// grails-app/domain/demo/Widget.groovy
package demo

class Widget {
    String name
    transient List firstTransientList
    transient List secondTransientList

    static constraints = {
        secondTransientList bindable: true
    }
}
Run Code Online (Sandbox Code Playgroud)

该测试将通过:

// test/unit/demo/WidgetSpec.groovy
package demo

import grails.test.mixin.TestFor
import spock.lang.Specification

@TestFor(Widget)
class WidgetSpec extends Specification {

    void "test binding to transient fields"() {
        when: 'binding to transient properties using named arguments'
        def widget = new Widget(firstTransientList: [1, 2, 3], 
                                secondTransientList: [4, 5, 6])

        then: 'by default transient fields are not bindable'
        widget.firstTransientList == null

        and: 'transient fields configured with bindable:true are bindable'
        widget.secondTransientList == [4, 5, 6]

        when: 'a value is assigned directly to a transient property'
        widget.firstTransientList = [7, 8, 9]

        then: 'the assignment succeeds'
        widget.firstTransientList == [7, 8, 9]
    }
}
Run Code Online (Sandbox Code Playgroud)

您还没有说过您使用的是哪个版本的Grails.2.3.x行中的某些行为发生了变化.上面的测试应该通过最新版本的Grails.

另一个编辑(回答下面评论中的问题):

可以在没有transient关键字的情况下定义瞬态属性,而是使用transients属性,如下所示:

// grails-app/domain/demo/Widget.groovy
package demo

class Widget {
    String name
    List firstTransientList
    List secondTransientList

    static transients = ['firstTransientList', 'secondTransientList']

    static constraints = {
        secondTransientList bindable: true
    }
}
Run Code Online (Sandbox Code Playgroud)