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
.
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.
Edit:
The dependency I want to get injected is springSecurityService
in my SecUser
subclass called Player
. The method that is failing is the encodePassword()
, which is called in the 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.
After changing to extend IntegrationSpec
, this is my test code:
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
:
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. Grails is supposed to do all the job for you :)
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:
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. 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
static loadExternalBeans = true //<-- loads resources.groovy beans
Source: 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With