Подтвердить что ты не робот

Инъекционные зависимости в тесте Grails Spock Specification

Мне нужно получить зависимости, введенные в мои объекты домена в моих тестах.

Эти тесты помещаются в каталог test/integration и простираются от spock.lang.Specification.

Как я могу это достичь?

Примечание. Я видел этот пост Как вставить spring beans в test test, но он не связан с grails.

Edit:

Зависимость, которую я хочу ввести, springSecurityService в моем подклассе SecUser называется Player. Сбой метода - это encodePassword(), который вызывается в beforeInsert().

Я могу издеваться над этим методом encodePassword() в некоторых тестах, но когда я хочу протестировать мой метод контроллеров save(), я не могу издеваться над созданным Player, потому что все это происходит внутри метода контроллеров.

После изменения расширения IntegrationSpec это мой тестовый код:

package intertigre.test.domain
import intertigre.domain.Fecha;
import intertigre.test.util.DomainFactoryTestService
import grails.plugin.spock.IntegrationSpec
import grails.test.mixin.TestFor

    @TestFor(Fecha)
    class FechaSpec extends IntegrationSpec{

    DomainFactoryTestService domainFactoryTestService = new DomainFactoryTestService()

    def 'test'(){
        given:
            def fecha = new Fecha()
        when:
            fecha.save()
        then:
            Fecha.get(1) == fecha
    }

}

Я получаю это исключение при запуске grails test-app :spock:

java.lang.NullPointerException: Cannot get property 'mainContext' on null object
    at grails.plugin.spock.IntegrationSpec.$spock_initializeSharedFields(IntegrationSpec.groovy)

И этот, когда я запускаю только тест:

| Failure:  intertigre.test.domain.FechaSpec
|  java.lang.NullPointerException: Cannot get property 'autowireCapableBeanFactory' on null object
    at grails.plugin.spock.IntegrationSpec.setupSpec(IntegrationSpec.groovy:47)
| Failure:  intertigre.test.domain.FechaSpec
|  java.lang.NullPointerException: Cannot invoke method isActive() on null object
    at grails.test.mixin.support.GrailsUnitTestMixin.shutdownApplicationContext(GrailsUnitTestMixin.groovy:232)
    at org.spockframework.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:176)
    at org.spockframework.runtime.extension.builtin.JUnitFixtureMethodsExtension$FixtureType$FixtureMethodInterceptor.intercept(JUnitFixtureMethodsExtension.java:145)
    at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:84)
    at org.spockframework.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:176)
4b9b3361

Ответ 1

Попробуйте объявить функцию springSecurityService в тесте, как это было бы в контроллере. Grails должен выполнять всю работу за вас:)

Для теста интеграции вы делаете что-то вроде этого:

package intertigre.test.domain
import intertigre.domain.Fecha;
import intertigre.test.util.DomainFactoryTestService
import grails.plugin.spock.IntegrationSpec

class DomainFactoryTestServiceSpec extends IntegrationSpec{

def domainFactoryTestService // you dont need to create a new instance, it injected by spring

def 'test'(){
     given:
         // ...
     when:
         // ...
     then:
         // ....
 }

Если вам нужно протестировать определенный объект домена (как ваш класс Fecha), вам, вероятно, понадобится unit test, что-то вроде этого:

package intertigre.test.domain
import intertigre.domain.Fecha
import intertigre.test.util.DomainFactoryTestService
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification

@TestFor(Fecha)
@Mock([OtherObject1, OtherObject2])
class FechaSpec extends Specification {

def domainFactoryTestService // same thing here, if you need the service

def 'test'() {
     given:
         def fecha = new Fecha()
     and:
         def oo1 = new OtherObject1()
     when:
         // ...
     then:
         // ....
 }

Вы можете использовать unit test для тестирования сервисов, это зависит от того, что вы собираетесь тестировать (класс - сервис или "ситуация" - способ использования службы).

Ps. Конечно, этот код здесь не был протестирован и может содержать опечатки.:) Но я надеюсь, вы получите мое мнение о том, как тестировать.

Ответ 2

Принятый ответ выше подходит для модульных тестов контроллеров, которым требуются классы обслуживания.

Если вы определили другие spring управляемые beans в resource.groovy и нуждаетесь в их введении, вы можете добавить эту строку в начало своего класса спецификаций

static loadExternalBeans = true //<-- loads resources.groovy beans

Источник: http://grails.github.io/grails-doc/2.4.4/guide/testing.html#unitTesting

Добавление статической нагрузкиExternalBeans = определение истинного поля в класс unit test заставляет Grails unit test загружать все определения bean из grails-app/conf/spring/resources.groovy и grails-app/conf/spring/resources.xml.