【问题标题】:Inject dependencies in Grails Spock Specification test在 Grails Spock 规范测试中注入依赖项
【发布时间】:2012-08-13 04:35:14
【问题描述】:

我需要在我的测试中将依赖项注入到我的域对象中。

这些测试被放置在 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)

【问题讨论】:

  • @AutoWired,也许吧?当您运行测试时,您的 grails 应用程序是否正在运行?
  • 也许模拟这些依赖关系更好?没有注入哪些依赖项?编写一些示例代码来显示一个问题。
  • 我从未尝试在 Grails 中使用 @Autowired,我会尝试的。运行测试时我没有运行应用程序。
  • 我已经用更多数据更新了我的问题,我稍后会添加代码

标签: testing grails groovy dependency-injection spock


【解决方案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'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:
         // ....
 }

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

附言。当然,这里的这段代码没有经过测试,可能有错别字。 :) 但我希望你明白我关于如何测试的观点。

【讨论】:

  • 我实际上是在扩展规范而不是集成规范。当我尝试更改以扩展 IntegrationSpec 时,运行测试时出现以下异常: java.lang.NullPointerException: Cannot get property 'mainContext' on null object at grails.plugin.spock.IntegrationSpec.$spock_initializeSharedFields(IntegrationSpec.groovy)
  • 您应该在进行集成测试时扩展 IntegrationSpec code.google.com/p/grails-spock-examples/wiki/… 是否有声明 null mainContext 的点?您当前使用的是哪个版本的 spock 插件?可以加一段代码看看吗?
  • 我正在使用插件“:spock:0.6”。我从不将 mainContext 声明为变量。我已经用我的测试代码更新了问题
  • 我认为您混淆了单元测试和集成测试。集成测试并不意味着测试域类(使用 testfro 注释),而是测试服务或一堆实用程序(如命名查询)。无论如何,我将尝试使用您添加到问题中的代码来编辑我的答案。
  • 稍后我将上传一个给我同样问题的 controllerSpec 代码。我应该在这里使用单元测试吗?
【解决方案2】:

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

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

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

来源http://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 定义.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多