首页 文章

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

提问于
浏览
12

我需要在我的测试中获取在我的域对象中注入的依赖项 .

此测试放在test / integration目录中,并从 spock.lang.Specification 扩展 .

我怎样才能做到这一点?

注意:我看过这篇文章How to inject spring beans into spock test,但它与grails无关 .

编辑:

我想要注入的依赖项是 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)

2 回答

  • 12

    尝试将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's injected by spring
    
    def 'test'(){
         given:
             // ...
         when:
             // ...
         then:
             // ....
     }
    

    如果您需要测试特定的域对象(作为您的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:
             // ....
     }
    

    您也可以使用单元测试来测试服务,这取决于您要测试的内容(类 - 服务 - 或“情况” - 服务的使用方式 - ) .

    PS . 当然,此处的代码尚未经过测试,可能包含拼写错误 . :)但我希望你明白如何测试 .

  • 1

    上面接受的答案适用于需要注入服务类的控制器的单元测试 .

    如果您在resources.groovy中定义了其他Spring托管bean并需要注入它们,则可以在spec类的顶部添加此行

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

    Sourcehttp://grails.github.io/grails-doc/2.4.4/guide/testing.html#unitTesting

    将静态loadExternalBeans = true字段定义添加到单元测试类使得Grails单元测试运行时从grails-app / conf / spring / resources.groovy和grails-app / conf / spring / resources.xml文件加载所有bean定义 .

相关问题