#unit-testing #grails #groovy #spock #data-conversion
#модульное тестирование #grails #groovy #спок #преобразование данных
Вопрос:
Я новичок в Groovy и Grails. Тест Spock для объекта домена для проверки сохраняемости завершается неудачей из-за преобразования пустой строки в null. Вот код. Объект домена,
class Todo {
String name
Date createdDate
String priority
String status
static constraints = {
priority blank: true
}
}
Спецификация 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
}
}
Результатом grails test-app
является
Todo.list().size() == 2
| | |
| 1 false
[collab.todo.Todo : 1]
at collab.todo.TodoSpec.test persist(TodoSpec.groovy:18)
Я обнаружил, что пустая строка ''
в строке new Todo(name: 't2', createdDate: new Date(), priority: '', status: 'ok')
преобразуется null
путем отладки. Через некоторое время в Google я вижу, что в Grails есть функция преобразования пустых строк из веб-формы в null для сохранения, которая может быть отключена конфигурацией grails.databinding.convertEmptyStringsToNull = false
в Config.groovy. Но я не думаю, что это относится к Spock UT. Я пробовал, но это работает не так, как я думал.
Мне было интересно, почему пустая строка преобразуется в null в качестве параметра, передаваемого конструктору? Заранее спасибо.
Ответ №1:
Сейчас это немного сложно, но можно заставить работать довольно легко. Следующий тест проходит с Grails 2.3.9…
Класс домена:
// grails-app/domain/com/demo/Person.groovy
package com.demo
class Person {
String title
}
Config.groovy:
// grails-app/conf/Config.groovy
grails.databinding.convertEmptyStringsToNull = false
// ...
Модульный тест:
// 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 == ''
}
}
Ключ применяет ContollerUnitTestMixin к тестовому варианту, хотя на самом деле он не тестирует контроллер. См . https://jira.grails.org/browse/GRAILS-11136 .
Надеюсь, это поможет.
Комментарии:
1. Да, тест проходит после добавления
@TestMixin(grails.test.mixin.web.ControllerUnitTestMixin)
.2. для меня это просто решило огромную проблему, хотя grails не слишком впечатлил в этом, так много настроек и странное поведение по умолчанию! в любом случае спасибо!!
3. @soheildb «так много настроек и странное поведение по умолчанию» — Если у вас есть рекомендации по улучшению поведения по умолчанию, пожалуйста, отправьте запрос по адресу github.com/grails/grails-core/issues и мы посмотрим на это.
Ответ №2:
Преобразование пустых строк в null является особенностью привязки данных Grails, поэтому это будет происходить везде, где используется привязка данных. Одним из таких мест является вызов конструктора класса домена с аргументом map . Если вы не хотите, чтобы строка преобразовывалась в null, попробуйте это:
new Todo().priority = ''