Как заполнить доменные классы в Grails 3 для юнит-тестов
Мне было интересно, как создать мир объектов класса Domain для использования в моих модульных тестах. Каков наилучший подход?
Скажи, что это мой код, ServiceX:
List<Course> getAllCoursesByType(String type) {
List<Course> list = Course.findAllByType(type)
list
}
Это тест для ServiceX:
import grails.buildtestdata.mixin.Build
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification
@TestFor(ServiceX)
class ServiceXSpec extends Specification {
void "get all open courses"() {
given:
String type = "open"
when:
def list = service.getAllCoursesByType(type)
then:
list.size() == 4
}
}
Как я могу "предварительно заполнить" тестовую базу данных (память), чтобы у меня на самом деле было 4 таких объекта в списке?
3 ответа
Оказывается, вы можете добавлять / переопределять методы к классам домена (например), примерно так:
import grails.buildtestdata.mixin.Build
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification
import grails.test.mixin.Mock
@Mock([Course])
@TestFor(ServiceX)
class ServiceXSpec extends Specification {
void "get all open courses"() {
given:
String type = "open"
Course.metaclass.static.findAllByType = { String type -> [new Course()]}
when:
def list = service.getAllCoursesByType(type)
then:
list.size() == 1
}
}
Создайте интеграционный тест для этого. Смотрите пример здесь.
Это суждение о том, когда проверять, используя медленный интеграционный тест. Ключ должен проверить ваш код, а не код Grails/hibernate DB.
Интеграционные тесты не должны быть необходимы для основной части сервисного тестирования. Я думаю, вам нужен интеграционный тест для взаимодействия объектов в работающей системе с реальной БД. Я склонен делать это в тестах GUI с использованием GEB. Эти тесты обычно охватывают базовые сквозные сценарии. Это проверяет взаимодействие на стороне сервера и GUI с сервером.
В тестах GUI/GEB я не проверяю все перестановки и граничные условия обслуживания. Я делаю большую часть этого краевого тестирования в модульных тестах.
Я обнаружил, что с Grails, если одно простое действие с БД работает в интеграционном тесте, тогда большинство других простых действий с БД работают. Домен Grails макетов для save(), delete() и т. Д. Имитирует "реальные" действия БД. Примечание: они работают с объектами в памяти, так что это не совсем то же самое.
Я не использую Spock, но с JUnit я использую этот подход (все еще работает с Grails 3):
@TestFor(ServiceX)
@Mock([Course])
class ServiceXTests {
}
@Test
void testXYZ() {
def course= new Course(course: 'ABC')
assert course.save()
. . .
}
Похоже, что это поддерживается со Споком. Я бы предположил, что это создание доменных записей относится к разделу "данный" Спока. Также см. Тестирование Грааля.
Еще один замечательный ресурс - поиск источника в Grails на Github. Я многому научился на их примерах.