映射构造函数不会将字符串分配给Grails中的Object

时间:2017-06-25 01:39:14

标签: grails groovy

给出以下域类:

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中的错误吗?

1 个答案:

答案 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)
  }
}