给出以下域类:
class Dog {
Object name // changing the type to String fixes it
}
这个单元测试:
import grails.test.mixin.Mock
import grails.test.mixin.TestMixin
import grails.test.mixin.support.GrailsUnitTestMixin
import spock.lang.*
/**
* See the API for {@link grails.test.mixin.support.GrailsUnitTestMixin} for usage instructions
*/
@TestMixin(GrailsUnitTestMixin)
@Mock([Dog])
class DogSpec extends Specification {
def setup() {
}
def cleanup() {
}
void "test something"() {
Dog dog = new Dog(name:"sparky")
// dog.name = "sparky" // adding this line also fixes it
expect:"fix me"
dog.name == "sparky"
}
}
正在运行grails test-app
失败,但如果您将Dog.name
的类型更改为String
,则可以正常运行。调试让我意识到Dog.name
永远不会被分配,而是null
。如果我在如上构造它之后通过常规赋值设置dog.name
,则测试通过。
使用相同的地图构造函数赋值在Groovy Script中不会发生此问题。
我希望我的类型为Object
,因为它会因用例而异。
知道为什么会这样吗?这是Grails中的错误吗?
答案 0 :(得分:0)
我做了一些调试,我发现当一个字段接受一个Object时,grails框架不对这个属性进行数据绑定。
更具体地说,Dog#name字段在声明为Object时不属于属性的白名单。
这就是为什么这不起作用的原因。
如果要调试,请参阅
grails.web.databinding.DataBindingUtils#getBindingIncludeList(final Object object)
如果你在那里放置一个断点,你会看到grails如何生成属性的白名单。
我认为这很有意义,因为它与安全有关!
详细了解here
如果你想绑定一个Object字段,这段代码可以帮助你:
class Dog {
Object name
static constraints = {
name(bindable: true)
}
}