Designing Warp extension for testing Spring MVC
jmnarloch Jun 10, 2012 5:03 AMHi,
I had played with the alpha 1 of Warp and I have to say that it's pretty cool.
I came up with an idea to create an extension particular for testing SpringMVC, I hacked the code a bit and came up with fallowing result: https://github.com/jmnarloch/arquillian-extension-warp/tree/Spring/extension
The code is pretty simple, but it gives the proof of concept for this idea.
Edit: a test example that demonstrates the usage:
{code}
@WarpTest
@RunWith(Arquillian.class)
public class WelcomeControllerTestCase {
@Drone
WebDriver browser;
@ArquillianResource
URL contextPath;
@Deployment
public static WebArchive createDeployment() {
File[] libs = DependencyResolvers.use(MavenDependencyResolver.class)
.loadEffectivePom("pom.xml")
.artifacts("org.springframework:spring-webmvc:3.1.1.RELEASE")
.resolveAsFiles();
return ShrinkWrap.create(WebArchive.class, "spring-test.war").addClasses(WelcomeController.class)
.addAsWebInfResource("WEB-INF/web.xml", "web.xml")
.addAsWebInfResource("WEB-INF/welcome-servlet.xml", "welcome-servlet.xml")
.addAsWebInfResource("WEB-INF/jsp/welcome.jsp", "jsp/welcome.jsp")
.addAsLibraries(libs);
}
@Test
@RunAsClient
public void test() {
Warp.execute(new ClientAction() {
@Override
public void action() {
browser.navigate().to(contextPath + "welcome.do");
}
}).verify(new WelcomeControllerVerification());
}
public static class WelcomeControllerVerification extends ServerAssertion {
private static final long serialVersionUID = 1L;
@Inject
private ModelAndView modelAndView;
@AfterServlet
public void testWelcome() {
assertEquals("welcome", modelAndView.getViewName());
assertEquals("Warp welcomes!", modelAndView.getModel().get("message"));
}
}
}
{code}
The most inportant part is the org.jboss.arquillian.warp.extension.spring.TestDispatcherServlet (I was thinkng about renaming it rather into WarpDispatcherServlet) which captures the execution of the request and stores it in SpringMvcResult. The SpringMvcResult could be injected into the ServerAssertion in order to retrieve the execution state.
I'm planning to extend the code a bit.
- First I would like add additional properties to the SpringMvcResult. Ideas:
- Handler that was used for this request.
- HttpServletRequest
- Second thing, I would like create a shorcut for injecting the properties. In meaning injecting directly the properties stored in SpringMVCResult.
{code}
public static class WelcomeControllerVerification extends ServerAssertion {
@Inject
private SpringMvcResult mvcResult;
// instead of mvcResult.getModelAndView()
@Inject
private ModelAndView modelAndView;
// instead of mvcResult.getException()
@Inject
private Exception exception;
@AfterServlet
public void test() {
}
}
}
{code}
- I've used the javax.inject.Inject for marking the fields that need to be injected, but maybe it would be better to use some custom annotation like @ArquillinResource or something complety new like @SpringMvcResource (or @SpringMvcContext maybe) or similar.
Last thing. Is there a way to inject a ServletRequest into the extension code? I had used the BeforeServletEvent, which I think would be nice to have in SPI rather then in implementation, as workaround to retrieve the request object.