为什么将空字符串转换为null传递给Grails 2.4.0中的域对象的构造函数?

use*_*977 5 grails groovy unit-testing data-conversion spock

我是Groovy和Grails的新手.由于空字符串被转换为null,因此要测试持久化的域对象的Spock测试失败.这是代码.域对象,

class Todo {

    String name
    Date createdDate
    String priority
    String status

    static constraints = {
        priority blank: true
    }

}
Run Code Online (Sandbox Code Playgroud)

Spock规范,

@TestFor(Todo)
class TodoSpec extends Specification {

    void "test persist"() {
        when:
        new Todo(name: 't1', createdDate: new Date(), priority: "1", status: 'ok').save()
        new Todo(name: 't2', createdDate: new Date(), priority: '', status: 'ok').save()

        then:
        Todo.list().size() == 2
    }

}
Run Code Online (Sandbox Code Playgroud)

结果grails test-app

Todo.list().size() == 2
     |      |      |
     |      1      false
     [collab.todo.Todo : 1]
        at collab.todo.TodoSpec.test persist(TodoSpec.groovy:18)
Run Code Online (Sandbox Code Playgroud)

我找到的空字符串''在该行new Todo(name: 't2', createdDate: new Date(), priority: '', status: 'ok')被转换成null由调试.谷歌一段时间之后,我发现Grails中有一个功能将空字符串从Web表单转换为null以保持不变,这可以通过grails.databinding.convertEmptyStringsToNull = falseConfig.groovy中的配置禁用.但我不认为这是Spock UT的情况.我已经尝试过,但它没有按照我的想法运作.

我想知道为什么空字符串转换为null作为传递给构造函数的参数?提前致谢.

Jef*_*own 6

它现在有点小,但可以很容易地工作.以下测试通过Grails 2.3.9 ...

域类:

// grails-app/domain/com/demo/Person.groovy
package com.demo

class Person {
    String title
}
Run Code Online (Sandbox Code Playgroud)

Config.groovy中:

// grails-app/conf/Config.groovy
grails.databinding.convertEmptyStringsToNull = false

// ...
Run Code Online (Sandbox Code Playgroud)

单元测试:

// test/unit/com/demo/PersonSpec.groovy
package com.demo

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

@TestFor(Person)
@TestMixin(grails.test.mixin.web.ControllerUnitTestMixin)
class PersonSpec extends Specification {

    void "test empty string conversion"() {
        when:
        def p = new Person(title: '')

        then:
        p.title == ''
    }
}
Run Code Online (Sandbox Code Playgroud)

关键是将ContollerUnitTestMixin应用于测试用例,即使它没有真正测试控制器.请参阅https://jira.grails.org/browse/GRAILS-11136.

我希望有所帮助.