简体   繁体   English

在Grails Spock规范测试中注入依赖项

[英]Inject dependencies in Grails Spock Specification test

I need to get the dependencies injected in my domain objects in my tests. 我需要在我的测试中获取在我的域对象中注入的依赖项。

This tests are placed in the test/integration directory and extends from spock.lang.Specification . 此测试放在test / integration目录中,并从spock.lang.Specification扩展。

How can I achieve this? 我怎样才能做到这一点?

Note: I've seen this post How to inject spring beans into spock test , but it is not related with grails. 注意:我已经看过这篇文章如何将春豆注入spock测试 ,但它与grails无关。

Edit: 编辑:

The dependency I want to get injected is springSecurityService in my SecUser subclass called Player . 我想获得注入的依赖是springSecurityServiceSecUser称为子类Player The method that is failing is the encodePassword() , which is called in the beforeInsert() . 失败的方法是encodePassword() ,它在beforeInsert()调用。

I can mock this encodePassword() method in some tests, but when I want to test my controllers method save() , I can't mock the Player that is being created because it all happens inside the controllers method. 我可以在某些测试中模拟这个encodePassword()方法,但是当我想测试我的控制器方法save() ,我无法模拟正在创建的Player ,因为它全部发生在controllers方法中。

After changing to extend IntegrationSpec , this is my test code: 更改为扩展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
    }

}

I'm getting this exception when running grails test-app :spock : 我在运行grails test-app :spock时遇到此异常grails test-app :spock

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

And this one when I run the test alone: 当我单独进行测试时这个:

| 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)

Try declaring the springSecurityService into the test, as you would do in a controller. 尝试将springSecurityService声明为测试,就像在控制器中一样。 Grails is supposed to do all the job for you :) Grails应该为你完成所有的工作:)

For an integration test you do something like this: 对于集成测试,您可以执行以下操作:

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's injected by spring

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

If you need to test a specific domain object (as your Fecha class), you probably need a unit test, something like this: 如果您需要测试特定的域对象(作为您的Fecha类),您可能需要进行单元测试,如下所示:

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:
         // ....
 }

You can use unit test to test services as well, it depends on what are you going to test (a class -the service- or a "situation" -the way the service is used-). 您也可以使用单元测试来测试服务,这取决于您要测试的内容(类 - 服务 - 或“情况” - 服务的使用方式 - )。

Ps. PS。 Of course, this code here hasn't been tested and can contain typos. 当然,此处的代码尚未经过测试,可能包含拼写错误。 :) But I hope you get my point about how to test. :)但我希望你明白如何测试。

Accepted answer above is good for unit tests of controllers that need service classes injected. 上面接受的答案适用于需要注入服务类的控制器的单元测试。

If you defined other spring managed beans in the resources.groovy and need them injected you can add this line at the top of your spec class 如果您在resources.groovy中定义了其他spring托管bean并且需要注入它们,则可以在spec类的顶部添加此行

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

Source : http://grails.github.io/grails-doc/2.4.4/guide/testing.html#unitTesting 资料来源http//grails.github.io/grails-doc/2.4.4/guide/testing.html#unitTesting

Adding static loadExternalBeans = true field definition to a unit test class makes the Grails unit test runtime load all bean definitions from grails-app/conf/spring/resources.groovy and grails-app/conf/spring/resources.xml files. 将静态loadExternalBeans = true字段定义添加到单元测试类使得Grails单元测试运行时从grails-app / conf / spring / resources.groovy和grails-app / conf / spring / resources.xml文件加载所有bean定义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM