我需要在我的测试中将我的域对象中的依赖项注入。
此测试放在测试/集成目录中,并从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)
答案 0 :(得分: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:
// ....
}
您也可以使用单元测试来测试服务,这取决于您要测试的内容(类 - 服务 - 或“情况” - 服务的使用方式 - )。
聚苯乙烯。当然,此处的代码尚未经过测试,可能包含拼写错误。 :)但我希望你明白如何测试。
答案 1 :(得分:1)
上面接受的答案适用于需要注入服务类的控制器的单元测试。
如果您在resources.groovy中定义了其他spring托管bean并需要注入它们,则可以在spec类的顶部添加此行
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定义