Как заполнить доменные классы в 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. Я многому научился на их примерах.

Другие вопросы по тегам