Re: [Stripes-users] Solved: Spring + Mockito
Glad it worked for you. And thanks for the explanation. It's much clearer than my ambiguous one :-) Regards, Iwao 2011/2/23 Marcus Kraßmann : > Hi Iwao, > > Today I sucessfully tried your way. It took just 10 minutes and works like a > charme. Just created a new SpringTestInterceptor with the same code like the > original one, but changed calls of SpringHelper to SpringTestHelper. This > offers the same inject methods like SpringHelper, but retrieves the > ApplicationContext like this: > > ApplicationContext ac = (ApplicationContext) > ctx.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); > > All other logic is delegated to SpringHelper. This way, no illegal cast > occurs and I can use @Autowired again. Thanks for pointing me to this. > > Kind regards, > Marcus -- Free Software Download: Index, Search & Analyze Logs and other IT data in Real-Time with Splunk. Collect, index and harness all the fast moving IT data generated by your applications, servers and devices whether physical, virtual or in the cloud. Deliver compliance at lower cost and gain new business insights. http://p.sf.net/sfu/splunk-dev2dev ___ Stripes-users mailing list Stripes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/stripes-users
Re: [Stripes-users] Solved: Spring + Mockito
Hi Iwao, Today I sucessfully tried your way. It took just 10 minutes and works like a charme. Just created a new SpringTestInterceptor with the same code like the original one, but changed calls of SpringHelper to SpringTestHelper. This offers the same inject methods like SpringHelper, but retrieves the ApplicationContext like this: ApplicationContext ac = (ApplicationContext) ctx.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); All other logic is delegated to SpringHelper. This way, no illegal cast occurs and I can use @Autowired again. Thanks for pointing me to this. Kind regards, Marcus - Ursprüngliche Mail - Von: "Iwao AVE!" An: "Stripes Users List" Gesendet: Dienstag, 22. Februar 2011 15:12:16 Betreff: Re: [Stripes-users] Spring + Mockito Hi Marcus, I was testing my action beans as Remi suggested, so it should work. Currently, I use a custom interceptor and a modified version of SpringHelper to create/inject mock spring beans into an action bean automatically. As it's a little bit tricky to explain, I would create a simple example project and upload it to somewhere if you are interested. Regards, Iwao 2011/2/22 Marcus Kraßmann : > Hi Remi, > > ctx.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEX_ATTRIBUTE, > springContext) > > I also had this idea some weeks ago. I cannot surely remember the reason why > I dropped it, but I think that I was not able to "convert" the > ApplicationContext used by JUnit to a WebApplicationContext that is needed > for the whole servlet thing. So your approach fails IIRC. > > Maybe someday I will review the whole thing and find a way to make your > approach work. That would be the best way: Using the "Spring test context" in > Stripes. > > Best wishes, > Marcus > > - Ursprüngliche Mail - > Von: "VANKEISBELCK Remi" > An: "Stripes Users List" > CC: "Marcus Kraßmann" > Gesendet: Dienstag, 22. Februar 2011 14:44:04 > Betreff: Re: [Stripes-users] Spring + Mockito > > Btw, what about : > > // create the Spring context for our test > ApplicationContext appCtx = createSpringAppCtx() > // play with the mockito bean > LoginService ls = (LoginService)appCtx.getBean(...) > ... > // create a mock servlet context, without the Spring context loader > MockServletContext ctx = createMockServletContextWithoutSpring() > // add Spring to the servlet context > ctx.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEX_ATTRIBUTE) > // and now do the roundtrip > MockRoundtrip trip = new MockRoundtrip(ctx, MyAction.class) > trip.xyz() > > ? > > Cheers > > Remi > > > 2011/2/22 VANKEISBELCK Remi < r...@rvkb.com > > > > Yeah your "first attempt" makes much more sense than this static field :) > > One thing though, what do you mean by "injecting into JUnit" ? > > From what I understood, you want to configure the mock object *prior* to > performing a mock round trip, don't you ? > > Cheers > > > > > Remi > > > 2011/2/22 Marcus Kraßmann < m...@syn-online.de > > > > Hi Remi, > > Thanks for your reply. Actually I have to wrap it because MockRoundtrip uses > another Spring ApplicationContext than JUnit itself. Fact is that if I inject > LoginService into JUnit (which is configured to be a singleton instance of > MockitoLoginService), then it is another instance than the one that is > injected into my action bean. > > Surely I could write a simple mock object that behaves the way I want without > Mockito. But by using Mockito, I can configure my test stubs very easily > without writing much code. At least in theory. > > If that still does not help to clearify my problem: > My first try was to declare a Mockito stub as Spring bean by declaring this > in my applicationContext.xml: > > scope="singleton"> > > > > This _should_ work fine, but is doesn't. The service is created twice, once > when starting up my JUnit tests, and the second time when the StripesFilter > is initialized in my test fixture. So if I configure a mocked LoginService in > JUnit, I configure another object than the one used by MockRoundtrip. > > Hope that this helps to understand the issue. I know that this is quite > "advanced" stuff. I just hope that someone else hat at least a similar issue > and knows a fine solution for the "two Spring contexts" problem :-) > > Best regards, > Marcus > > - Ursprüngliche Mail - > Von: "VANKEISBELCK Remi" < r...@rvkb.com > > An: "Stripes Users List" < stripes-users@lists.sourceforge.net > > CC: "Marcus Kraßmann" < m...@syn-online.de > > Gesendet: Dienstag, 22. Februar 2011 13:38:36 > Betreff: Re: [Stripes-users] Spring + Mockito > > > > > Hi Marcus, > > Not sure I understand what you're trying to do... > > Why do you have to wrap the mock ? > > Cheers > > Remi > > > 2011/2/22 Marcus Kraßmann < m...@syn-online.de > > > > Hi Stripes Users, > > Currently I want to test an action bean. It gets a Spring bean (service > class) injected via the @SpringBean annotation. Now I want this service
Re: [Stripes-users] Solved: Spring + Mockito
I had no idea you could do this kind of Spring/JUnit integration. Looks cool. It probably has a way to tell it to use some supplied ApplicationContext though, instead of creating one itself... Like injecting the bean factory itself (??? :P) Cheers Remi 2011/2/22 Marcus Kraßmann > Well, my test case looks like this: > > @RunWith(SpringJUnit4ClassRunner.class) > @TestExecutionListeners( { DependencyInjectionTestExecutionListener.class, >DirtiesContextTestExecutionListener.class}) > @ContextConfiguration(locations = "classpath:test-context.xml") > public class LogoutActionBeanTest { > >@Autowired >private LoginService loginService; > >@Test >public void validCredentials() throws Exception { >MockHttpSession session = new MockHttpSession(CTX); >when(loginService.login(anyString(), anyString())).thenReturn(new > User()); > >MockRoundtrip trip = new MockRoundtrip(CTX, LoginActionBean.class, > session); >trip.setParameter("username", username); >trip.setParameter("password", "testpass"); >trip.execute("login"); > >assertNotNull(session.getAttribute("user")); >} > } > > Here I let Spring fill in the mocked LoginService. This is what I called > "inject into JUnit". > > Now the solution: > Instead of using @Autowired to get an instance of my mocked bean, I created > the following method in my test fixture: > > protected T getBean(String beanname, Class clazz) { >return > WebApplicationContextUtils.getWebApplicationContext(CTX).getBean(beanname, > clazz); > } > > This way I can retrieve the Spring bean instance used by Stripes, within my > unit test. Not a perfect solution as there are still two Spring contexts, > but it is good enough :-) > > Best regards, > Marcus > > - Ursprüngliche Mail - > Von: "VANKEISBELCK Remi" > An: "Stripes Users List" > CC: "Marcus Kraßmann" > Gesendet: Dienstag, 22. Februar 2011 14:33:02 > Betreff: Re: [Stripes-users] Spring + Mockito > > Yeah your "first attempt" makes much more sense than this static field :) > > One thing though, what do you mean by "injecting into JUnit" ? > > From what I understood, you want to configure the mock object *prior* to > performing a mock round trip, don't you ? > > Cheers > > Remi > > > 2011/2/22 Marcus Kraßmann < m...@syn-online.de > > > > Hi Remi, > > Thanks for your reply. Actually I have to wrap it because MockRoundtrip > uses another Spring ApplicationContext than JUnit itself. Fact is that if I > inject LoginService into JUnit (which is configured to be a singleton > instance of MockitoLoginService), then it is another instance than the one > that is injected into my action bean. > > Surely I could write a simple mock object that behaves the way I want > without Mockito. But by using Mockito, I can configure my test stubs very > easily without writing much code. At least in theory. > > If that still does not help to clearify my problem: > My first try was to declare a Mockito stub as Spring bean by declaring this > in my applicationContext.xml: > > scope="singleton"> > > > > This _should_ work fine, but is doesn't. The service is created twice, once > when starting up my JUnit tests, and the second time when the StripesFilter > is initialized in my test fixture. So if I configure a mocked LoginService > in JUnit, I configure another object than the one used by MockRoundtrip. > > Hope that this helps to understand the issue. I know that this is quite > "advanced" stuff. I just hope that someone else hat at least a similar issue > and knows a fine solution for the "two Spring contexts" problem :-) > > Best regards, > Marcus > > - Ursprüngliche Mail - > Von: "VANKEISBELCK Remi" < r...@rvkb.com > > An: "Stripes Users List" < stripes-users@lists.sourceforge.net > > CC: "Marcus Kraßmann" < m...@syn-online.de > > Gesendet: Dienstag, 22. Februar 2011 13:38:36 > Betreff: Re: [Stripes-users] Spring + Mockito > > > > > Hi Marcus, > > Not sure I understand what you're trying to do... > > Why do you have to wrap the mock ? > > Cheers > > Remi > > > 2011/2/22 Marcus Kraßmann < m...@syn-online.de > > > > Hi Stripes Users, > > Currently I want to test an action bean. It gets a Spring bean (service > class) injected via the @SpringBean annotation. Now I want this service to > be mocked with Mockito. My current solution works like this: > > I have an interface "LoginService" and a real implementation > "LoginServiceImpl" annotated with @Service annotation. In my test classpath, > I also have an implementation called MockitoLoginService which uses the > decorator pattern. It has the following static (!) field: > > public static final LoginService mock = mock(LoginService.class); > > The login method derived from the interface looks like this: > > public User login(String username, String password) throws LoginException { > return mock.login(username, password); > } > > This enables me to configure the mocked service from my unit test by > config
[Stripes-users] Solved: Spring + Mockito
Well, my test case looks like this: @RunWith(SpringJUnit4ClassRunner.class) @TestExecutionListeners( { DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class}) @ContextConfiguration(locations = "classpath:test-context.xml") public class LogoutActionBeanTest { @Autowired private LoginService loginService; @Test public void validCredentials() throws Exception { MockHttpSession session = new MockHttpSession(CTX); when(loginService.login(anyString(), anyString())).thenReturn(new User()); MockRoundtrip trip = new MockRoundtrip(CTX, LoginActionBean.class, session); trip.setParameter("username", username); trip.setParameter("password", "testpass"); trip.execute("login"); assertNotNull(session.getAttribute("user")); } } Here I let Spring fill in the mocked LoginService. This is what I called "inject into JUnit". Now the solution: Instead of using @Autowired to get an instance of my mocked bean, I created the following method in my test fixture: protected T getBean(String beanname, Class clazz) { return WebApplicationContextUtils.getWebApplicationContext(CTX).getBean(beanname, clazz); } This way I can retrieve the Spring bean instance used by Stripes, within my unit test. Not a perfect solution as there are still two Spring contexts, but it is good enough :-) Best regards, Marcus - Ursprüngliche Mail - Von: "VANKEISBELCK Remi" An: "Stripes Users List" CC: "Marcus Kraßmann" Gesendet: Dienstag, 22. Februar 2011 14:33:02 Betreff: Re: [Stripes-users] Spring + Mockito Yeah your "first attempt" makes much more sense than this static field :) One thing though, what do you mean by "injecting into JUnit" ? From what I understood, you want to configure the mock object *prior* to performing a mock round trip, don't you ? Cheers Remi 2011/2/22 Marcus Kraßmann < m...@syn-online.de > Hi Remi, Thanks for your reply. Actually I have to wrap it because MockRoundtrip uses another Spring ApplicationContext than JUnit itself. Fact is that if I inject LoginService into JUnit (which is configured to be a singleton instance of MockitoLoginService), then it is another instance than the one that is injected into my action bean. Surely I could write a simple mock object that behaves the way I want without Mockito. But by using Mockito, I can configure my test stubs very easily without writing much code. At least in theory. If that still does not help to clearify my problem: My first try was to declare a Mockito stub as Spring bean by declaring this in my applicationContext.xml: This _should_ work fine, but is doesn't. The service is created twice, once when starting up my JUnit tests, and the second time when the StripesFilter is initialized in my test fixture. So if I configure a mocked LoginService in JUnit, I configure another object than the one used by MockRoundtrip. Hope that this helps to understand the issue. I know that this is quite "advanced" stuff. I just hope that someone else hat at least a similar issue and knows a fine solution for the "two Spring contexts" problem :-) Best regards, Marcus - Ursprüngliche Mail - Von: "VANKEISBELCK Remi" < r...@rvkb.com > An: "Stripes Users List" < stripes-users@lists.sourceforge.net > CC: "Marcus Kraßmann" < m...@syn-online.de > Gesendet: Dienstag, 22. Februar 2011 13:38:36 Betreff: Re: [Stripes-users] Spring + Mockito Hi Marcus, Not sure I understand what you're trying to do... Why do you have to wrap the mock ? Cheers Remi 2011/2/22 Marcus Kraßmann < m...@syn-online.de > Hi Stripes Users, Currently I want to test an action bean. It gets a Spring bean (service class) injected via the @SpringBean annotation. Now I want this service to be mocked with Mockito. My current solution works like this: I have an interface "LoginService" and a real implementation "LoginServiceImpl" annotated with @Service annotation. In my test classpath, I also have an implementation called MockitoLoginService which uses the decorator pattern. It has the following static (!) field: public static final LoginService mock = mock(LoginService.class); The login method derived from the interface looks like this: public User login(String username, String password) throws LoginException { return mock.login(username, password); } This enables me to configure the mocked service from my unit test by configuring the "mock" constant: when(MockitoLoginService.mock.login(anyString(), anyString())).thenReturn(new User()); Why did I make the field static? Well, when executing LoginActionBean with MockRoundtrip, a new Spring context is created. If "mock" was an instance field, it would also be newly created for the action bean, so I cannot configure the mock object of the MockitoLoginService that was injected into my unit test. By using a static field, this pr