Quantcast

@TestFor with @Autowire

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

@TestFor with @Autowire

rfeldman
I have the following controller:

class SomeController {
    @Autowired SomeService someService
}

I'm trying to test it out with:

@TestFor(SomeController)
class SomeControllerTests {
   
}

However, as soon as @TestFor sets up the Spring context, the test fails because the @Autowired dependency fails.

What I want to do is to inject a mock instance of SomeService into the controller instance generated by @TestFor - easy to do if no @Autowired is involved, as I can just set it in the test or in an @Before method, but so far I'm stumped as to how to get around the timing problem. @TestFor sets up the ApplicationContext, including autowiring (which there's no way to disable for the test, as far as I can tell), before I can run a line of code - so I have no chance to inject mocks; the autowired dependency fails to be satisfied every time.

Is there any workaround to this? I assume I'm not the only one trying to use @Autowired and @TestFor, but I can't seem to find any other posts concerning how to handle this.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: @TestFor with @Autowire

basejump (Josh)
Wait, are you using up a normal grails controller?
Why do you need @Autowired in there?

On Jul 2, 2011, at 2:18 PM, rfeldman wrote:

> I have the following controller:
>
> class SomeController {
>    @Autowired SomeService someService
> }
>
> I'm trying to test it out with:
>
> @TestFor(SomeController)
> class SomeControllerTests {
>
> }
>
> However, as soon as @TestFor sets up the Spring context, the test fails
> because the @Autowired dependency fails.
>
> What I want to do is to inject a mock instance of SomeService into the
> controller instance generated by @TestFor - easy to do if no @Autowired is
> involved, as I can just set it in the test or in an @Before method, but so
> far I'm stumped as to how to get around the timing problem. @TestFor sets up
> the ApplicationContext, including autowiring (which there's no way to
> disable for the test, as far as I can tell), before I can run a line of code
> - so I have no chance to inject mocks; the autowired dependency fails to be
> satisfied every time.
>
> Is there any workaround to this? I assume I'm not the only one trying to use
> @Autowired and @TestFor, but I can't seem to find any other posts concerning
> how to handle this.
>
> --
> View this message in context: http://grails.1312388.n4.nabble.com/TestFor-with-Autowire-tp3641014p3641014.html
> Sent from the Grails - user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: @TestFor with @Autowire

rfeldman
We're converting a SpringMVC app to Grails...everything is using @Autowired for autowiring by type (since Grails uses autowire by name for its autowiring).

I guess the best workaround could be to switch to autowiring by name and rewriting a bunch of services...but if there's a way to do it with autowire by type, I'd certainly rather do that. :)
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: @TestFor with @Autowire

Graeme Rocher-4
Administrator
In this case you will need to not use the annotation and instead do
something like this

@TestMixin(ControllerUnitTestMixin)
class SimpleControllerTests {

     void setUp() {
         defineBeans { someService(SomeService) }
         testFor(SimpleController)
     }
}

The problem is the controller is registered with the application
context and the bean is not available with @TestFor

Cheers

On Sun, Jul 3, 2011 at 2:52 AM, rfeldman <[hidden email]> wrote:

> We're converting a SpringMVC app to Grails...everything is using @Autowired
> for autowiring by type (since Grails uses autowire by name for its
> autowiring).
>
> I guess the best workaround could be to switch to autowiring by name and
> rewriting a bunch of services...but if there's a way to do it with autowire
> by type, I'd certainly rather do that. :)
>
> --
> View this message in context: http://grails.1312388.n4.nabble.com/TestFor-with-Autowire-tp3641014p3641353.html
> Sent from the Grails - user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>
>



--
Graeme Rocher
Grails Project Lead
SpringSource - A Division of VMware
http://www.springsource.com

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: @TestFor with @Autowire

rfeldman

Beautiful, thank you Graeme!

On Jul 4, 2011 2:23 AM, "Graeme Rocher-4 [via Grails]" <[hidden email]> wrote:
>
>
> In this case you will need to not use the annotation and instead do
> something like this
>
> @TestMixin(ControllerUnitTestMixin)
> class SimpleControllerTests {
>
> void setUp() {
> defineBeans { someService(SomeService) }
> testFor(SimpleController)
> }
> }
>
> The problem is the controller is registered with the application
> context and the bean is not available with @TestFor
>
> Cheers
>
> On Sun, Jul 3, 2011 at 2:52 AM, rfeldman <[hidden email]> wrote:
>> We're converting a SpringMVC app to Grails...everything is using @Autowired
>> for autowiring by type (since Grails uses autowire by name for its
>> autowiring).
>>
>> I guess the best workaround could be to switch to autowiring by name and
>> rewriting a bunch of services...but if there's a way to do it with autowire
>> by type, I'd certainly rather do that. :)
>>
>> --
>> View this message in context: http://grails.1312388.n4.nabble.com/TestFor-with-Autowire-tp3641014p3641353.html
>> Sent from the Grails - user mailing list archive at Nabble.com.
>>
>> ---------------------------------------------------------------------
>> To unsubscribe from this list, please visit:
>>

>>    http://xircles.codehaus.org/manage_email
>>
>>
>>
>
>
>
> --
> Graeme Rocher
> Grails Project Lead
> SpringSource - A Division of VMware
> http://www.springsource.com
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
> http://xircles.codehaus.org/manage_email
>
>
>
>
> _______________________________________________
> If you reply to this email, your message will be added to the discussion below:
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: @TestFor with @Autowire

fiallega
I have tried the following example

import grails.test.mixin.*
import grails.test.mixin.support.*
import grails.test.mixin.web.*

import org.junit.*


@TestMixin(ControllerUnitTestMixin)
class GreetControllerTests {

        @Before
        void setUp() {
                println "setting up"
                GrailsUnitTestMixin.defineBeans { greetMeService(GreetMeService)
                         }
                testFor(GreetController)
        }
       
        @Test
    void testSomething() {
                controller.hello()
                assert response.text == "good morning"
    }
}

I get
java.lang.NullPointerException: Cannot invoke method isActive() on null object
        at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:77)
        at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:45)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
        at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:32)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
        at grails.test.mixin.web.ControllerUnitTestMixin.bindGrailsWebRequest(ControllerUnitTestMixin.groovy:210)
        at grails.test.mixin.web.ControllerUnitTestMixin.mockController(ControllerUnitTestMixin.groovy:246)
        at grails.test.mixin.web.ControllerUnitTestMixin.testFor(ControllerUnitTestMixin.groovy

So I could not get the injection of beans in the testing of controller working.
I also tried the documentation http://grails.org/doc/2.0.0.M1/guide/single.html#testing under 'Testing Spring Beans' and I could not get it to work either. (null pointer exception because the service bean was never injected)
Any ideas what I might be doing wrong ?
Loading...