integration testing spring controllers

28
Lightning Talk by Ted Young Integration Testing Spring Controllers

Upload: nickan

Post on 24-Feb-2016

59 views

Category:

Documents


0 download

DESCRIPTION

Integration Testing Spring Controllers. Lightning Talk by Ted Young. What is Integration Testing?. Unit Versus Integration Tests. Unit Versus Integration Tests. Unit Versus Integration Tests. Unit Tests Aren’t Always Best. public void persist(Foo foo) { entityManager .persist (foo ); } - PowerPoint PPT Presentation

TRANSCRIPT

Integration Testing Spring Controllers

Lightning Talk by Ted YoungIntegration Testing Spring ControllersWhat is Integration Testing?Test an entire stack, or collection of relationships. Best described by comparing to unit tests.2Unit TestIntegration TestIsolationEntire StackUnit Versus Integration TestsUnit TestIntegration TestIsolationEntire StackInject MocksInject ImplementationsUnit Versus Integration TestsUnit TestIntegration TestIsolationEntire StackInject MocksInject ImplementationsVerifies CodeVerifies ApplicationUnit Versus Integration Testspublic void persist(Foo foo) {entityManager.persist(foo);}

public List find() {return entityManager.createQuery("from Foo").getResultList();}

public List findByName(String name) {CriteriaBuilder cb = entityManager.getCriteriaBuilder();CriteriaQuery query = cb.createQuery(Foo.class);Root root = query.from(Foo.class);query.where(cb.equal(root.get(Foo_.name), name));return entityManager.createQuery(query).getResultList();}Unit Tests Arent Always BestConsider this repository Do you want to write unit tests for this? Your unit end up testing that you wrote your code in a certain way.Controllers often end up the same way. You can unit test them, but you can test your entire app by integration testing them.6External Tool (e.g. JMeter)Test Harness (e.g. JUnit)External ToolIDE, Maven, CI, etc.Integration Testing ControllersPros: part of CI testing, build cycle, can run anytime (do not need to deploy application to a test server).7External Tool (e.g. JMeter)Test Harness (e.g. JUnit)External ToolIDE, Maven, CI, etc.Script ActionsBuild Requests in JavaIntegration Testing ControllersPros: type safe, refactorable, test code reuse.8External Tool (e.g. JMeter)Test Harness (e.g. JUnit)External ToolIDE, Maven, CI, etc.Script ActionsBuild Requests in JavaNo Knowledge of ApplicationIntimate Knowledge of Application:Security SystemData ModelMake Use of SpringIntegration Testing ControllersPros: Security: do not need to script login and logout.Data Model: can preconstruct data model for a test and inspect it afterwards; makes for much simpler, more comprehensive tests.Spring: use spring for testing and configuration.9External Tool (e.g. JMeter)Test Harness (e.g. JUnit)External ToolIDE, Maven, CI, etc.Script ActionsBuild Requests in JavaNo Knowledge of ApplicationIntimate Knowledge of Application:Security SystemData ModelMake Use of SpringRefactor = RewriteMake Use of IDE ToolsIntegration Testing ControllersPros: Security: do not need to script login and logout.Data Model: can preconstruct data model for a test and inspect it afterwards; makes for much simpler, more comprehensive tests.Spring: use spring for testing and configuration.10External Tool (e.g. JMeter)Test Harness (e.g. JUnit)External ToolIDE, Maven, CI, etc.Script ActionsBuild Requests in JavaNo Knowledge of ApplicationIntimate Knowledge of Application:Security SystemData ModelMake Use of SpringRefactor = RewriteMake Use of IDE ToolsErrors at RuntimeErrors at CompiletimeIntegration Testing ControllersPros: Security: do not need to script login and logout.Data Model: can preconstruct data model for a test and inspect it afterwards; makes for much simpler, more comprehensive tests.Spring: use spring for testing and configuration.11Testing a ControllerServlet ContainerControllerNormal controllers are built directly on the servlet API and require a servlet container.12Testing a Spring MVC ControllerServlet ContainerControllerSpring MVCSpring MVC isolates us from the servlet API. Theoretically, you can integration test your controllers without doing anything special.13Testing a Spring MVC ControllerServlet ContainerControllerSpring MVCView ResolutionTransactionsRequest MappingUnfortunately, we come to depend on a variety of services offered by spring14Testing a Spring MVC ControllerServlet ContainerControllerSpring MVCView ResolutionTransactionsRequest MappingDispatcherServletUnfortunately, these depend on DispatcherServlet, which depends on the presence of a servlet container... Or does it?15Mocking DispatcherServletDispatcherServletMocking DispatcherServletDispatcherServletWebApplicationContextBut, we need to give it an WebApplicationContext (and it needs to know where our config files are).17Mocking DispatcherServletDispatcherServletWebApplicationContextServletConfigServletContextAnd the webappcontext needs a servletconfig and servletcontext. Thanks to spring, these are all easy to mock up. However, it should be clear by the arrows that getting everything wired together right is not trivial.See my site for source code.18@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations="classpath:spring.xml")public class SomeControllerTests {...}

Spring and JUnit@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations="classpath:spring.xml", loader=MockWebApplicationContextLoader.class)public class SomeControllerTests {...}

Spring and JUnit@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations="classpath:spring.xml", loader=MockWebApplicationContextLoader.class)@MockWebApplication(name="some-controller",webapp="/src/main/webapp")public class SomeControllerTests {...}

Spring and JUnitHow Many Use:JSPsVelocityFreemarkerFaceletsView TechnologiesJSPs depend on a servlet container. There is no way to test the view layer. Precompiling is not equivalent!Velocity can be tested. Look for bad expressions, missing message codes, etc.Freemaker is better. Has support for taglibs (see footnote).Facelets are on your own. Theoretically can work.22@Autowiredprivate DispatcherServlet servlet;

@Autowiredprivate SomeRepository repository;

@Testpublic void viewTest() throws Exception {MockHttpServletRequest request = new MockHttpServletRequest("GET", "/view");

request.addParameter("id", "0");MockHttpServletResponse response = new MockHttpServletResponse();

servlet.service(request, response);String results = response.getContentAsString().trim();

Assert.assertEquals("Hello World!", results);}

An Example TestNotice that the MockWebApplicationContextLoader makes the mocked dispatcherservlet injectable by registering in the app context!23@Testpublic void saveTest() throws Exception {MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");

request.addParameter("name", "Ted");

MockHttpServletResponse response = new MockHttpServletResponse();

servlet.service(request, response);

Assert.assertEquals("Ted", repository.find(1).getName());}Prepare and Review Model@Test(expected=NestedServletException.class)public void saveFailedTest() throws Exception {MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");

request.addParameter("name", "");

MockHttpServletResponse response = new MockHttpServletResponse();

servlet.service(request, response);}Test ValidationJava Beans Validation with @Valid25@Test(expected=NestedServletException.class)public void secureFailedTest() throws Exception {MockHttpServletRequest request = new MockHttpServletRequest("GET", "/secure/view");MockHttpServletResponse response = new MockHttpServletResponse();

servlet.service(request, response);}Test Security@Testpublic void secureTest() throws Exception {SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken("Ted", "password"));

MockHttpServletRequest request = new MockHttpServletRequest("GET", "/secure/view");

MockHttpServletResponse response = new MockHttpServletResponse();

servlet.service(request, response);String results = response.getContentAsString().trim();

Assert.assertEquals("Hello Ted!",results);}Test Securityhttp://[email protected] Visit My SiteCode, examples, slides, and a complete article on this subject, as well as many other resources.28