Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Testing Spring MVC and REST Web Applications

2,207 views

Published on

The Spring Team has innovated extensively around testing in the past, and this innovation continues today. One of the most exciting recent additions to Spring's testing support is Spring MVC Test. What makes it so interesting is the comprehensive support for testing web applications and context hierarchies with the Spring TestContext Framework as well as comprehensive support for out-of-container Spring MVC and REST integration testing.

Join core Spring Framework committer Sam Brannen to see these new Spring Web testing features in action and learn how to speed up your development-test lifecycle.

Published in: Software
  • Be the first to comment

Testing Spring MVC and REST Web Applications

  1. 1. Testing Spring MVC and REST Web Applications Sam Brannen @sam_brannen Spring eXchange | London, England | 15 November 2013
  2. 2. 2 Sam Brannen •  Spring and Java Consultant @ Swiftmind •  Java Developer for over 15 years •  Spring Framework Core Committer since 2007 •  Spring Trainer •  Presenter on Spring, Java, OSGi, and testing
  3. 3. 3 Swiftmind Your experts for Enterprise Java Areas of expertise •  Spring * •  Java EE •  OSGi •  Agile Methodologies •  Software Engineering Best Practices Where you find us •  Zurich, Switzerland •  @swiftmind •  http://www.swiftmind.com
  4. 4. 4 A Show of Hands…
  5. 5. 5 Agenda •  Spring TestContext Framework Updates •  Spring MVC Test Framework •  Q & A
  6. 6. 6 Spring TestContext Framework Updates
  7. 7. 7 What’s New in the Spring TCF? •  Upgraded to JUnit 4.11 and TestNG 6.5.2 •  Loading a WebApplicationContext •  Testing request- and session-scoped beans •  Support for ApplicationContextInitializer •  Loading context hierarchies (3.2.2) •  Meta-annotation support for tests (4.0)
  8. 8. 8 Loading a WebApplicationContext Q: How do you tell the TestContext Framework to load a WebApplicationContext? A: Just annotate your test class with @WebAppConfiguration!
  9. 9. 9 @WebAppConfiguration •  Denotes that the context should be a WebApplicationContext •  Configures the resource path for the web app –  Used by MockServletContext –  Defaults to “src/main/webapp” –  Paths are file-system folders, relative to the project root, not class path resources –  The classpath: prefix is also supported
  10. 10. 10 @WAC – Default Values
  11. 11. 11 @WAC – Default Resource Types
  12. 12. 12 @WAC – Overrides
  13. 13. 13 ServletTestExecutionListener •  Sets up default thread-local state via RequestContextHolder before each test method •  Creates: –  MockHttpServletRequest –  MockHttpServletResponse –  ServletWebRequest •  Ensures that the MockHttpServletResponse and ServletWebRequest can be injected into the test instance •  Cleans up thread-local state after each test method
  14. 14. 14 Example: Injecting Mocks
  15. 15. 15 Web Scopes – Review request: lifecycle tied to the current HttpServletRequest session: lifecycle tied to the current HttpSession
  16. 16. 16 Example: Request-scoped Bean Config
  17. 17. 17 Example: Request-scoped Bean Test
  18. 18. 18 Example: Session-scoped Bean Config
  19. 19. 19 Example: Session-scoped Bean Test
  20. 20. 20 ApplicationContextInitalizer •  Introduced in Spring 3.1 •  Used for programmatic initialization of a ConfigurableApplicationContext •  For example: –  to register property sources –  to activate profiles against the Environment •  Configured in web.xml by specifying contextInitializerClasses via –  context-param for the ContextLoaderListener –  init-param for the DispatcherServlet
  21. 21. 21 Using Initializers in Tests •  Configured in @ContextConfiguration via the initializers attribute •  Inheritance can be controlled via the inheritInitializers attribute •  An ApplicationContextInitializer may configure the entire context –  XML resource locations or annotated classes are no longer required •  Initializers are now part of the context cache key •  Initializers are ordered based on Spring's Ordered interface or the @Order annotation
  22. 22. 22 Example: Multiple Initializers
  23. 23. 23 Application Context Hierarchies •  Traditionally only flat, non-hierarchical contexts were supported in tests. •  There was no easy way to create contexts with parent- child relationships. •  But… hierarchies are supported in production. •  Wouldn’t it be nice if you could test them, too?!
  24. 24. 24 Testing Context Hierarchies in 3.2.2 •  New @ContextHierarchy annotation –  Used in conjunction with @ContextConfiguration •  @ContextConfiguration now supports a ‘name’ attribute –  for merging and overriding hierarchy configuration
  25. 25. 25 Single Test with Context Hierarchy
  26. 26. 26 Class and Context Hierarchies
  27. 27. 27 Testing Changes in 4.0 Gone: –  JUnit 3.8 support –  @ExpectedException –  @NotTransactional –  SimpleJdbcTestUtils Updated: –  Servlet API mocks –  Spring MVC Test framework
  28. 28. 28 New Testing Features in 4.0 •  SocketUtils –  scan for UDP & TCP ports •  ActiveProfilesResolver –  alternative to static profile strings –  set via new resolver attribute in @ActiveProfiles •  Meta-annotation support for tests
  29. 29. 29 Meta-annotations in Tests @ContextConfiguration({ "/app-config.xml", "/test-config.xml" }) @ActiveProfiles("dev") @Transactional @Retention(RetentionPolicy.RUNTIME) public @interface TransactionalTest { } @TransactionalTest @RunWith(SpringJUnit4ClassRunner.class) public class UserRepositoryIntegrationTests { /* ... */ }
  30. 30. 30 Spring MVC Test Framework
  31. 31. 31 What is Spring MVC Test? •  Dedicated support for testing Spring MVC applications •  Fluent API •  Very easy to write •  Includes client and server-side support •  Servlet container not required
  32. 32. 32 Details •  Included in spring-test module of Spring Framework 3.2 •  Builds on –  TestContext framework for loading Spring MVC configuration –  MockHttpServlet[Request|Response] and other mock types •  Server-side tests involve DispatcherServlet •  Client-side REST testing for code using RestTemplate
  33. 33. 33 Spring MVC Test History •  Evolved as independent project on GitHub –  https://github.com/SpringSource/spring-test-mvc •  Now folded into Spring Framework 3.2 •  Former project still supports Spring Framework 3.1
  34. 34. 34 Server-side Example
  35. 35. 35 A Note of Fluent API Usage •  Requires static imports import static MockMvcRequestBuilders.get; import static MockMvcResultMatchers.status; mockMvc.perform(get(“/foo”)) .andExpect(status().isOk()) •  Add as “favorite static members” in Eclipse preferences –  Java -> Editor -> Content Assist -> Favorites
  36. 36. 36 Server-side Test Recap •  Actual Spring MVC configuration loaded •  MockHttpServletRequest prepared •  Executed via DispatcherServlet •  Assertions applied on the resulting MockHttpServletResponse
  37. 37. 37 Integration or Unit Testing? •  Mock request/response types, no Servlet container •  However … –  DispatcherServlet + actual Spring MVC configuration used •  Hence … –  Not full end-to-end testing; does not replace Selenium –  However provides full confidence in Spring MVC web layer •  In short, integration testing for Spring MVC –  Don't get too caught up in terminology!
  38. 38. 38 Strategy for Testing •  Focus on testing the Spring MVC web layer alone –  Inject controllers with mock services or database repositories •  Thoroughly test Spring MVC –  Including code and configuration •  Separate from lower layer integration tests –  e.g., data access tests
  39. 39. 39 Declaring a Mocked Dependency •  Since we're loading actual Spring MVC config … •  First declare mock dependency: <bean class="org.mockito.Mockito" factory-method="mock"> <constructor-arg value="org.example.FooRepository"/> </bean> •  Then simply inject the mock instance into the test class –  Via @Autowired or @Inject –  Set up and reset via @Before, @Test, and @After methods
  40. 40. 40 What can be tested? •  Response status, headers, and content –  Focus on asserting these first... •  Spring MVC and Servlet specific results –  Model, flash, session, request attributes –  Mapped controller method and interceptors –  Resolved exceptions •  Various options for asserting the response body –  JSONPath, XPath, XMLUnit –  Hamcrest matchers
  41. 41. 41 What about the view layer? •  All view templating technologies will work –  Freemarker, Velocity, Thymeleaf, JSON, XML, PDF, etc. •  Except for JSPs (no Servlet container!) –  But you can assert which JSP was selected •  No redirecting and forwarding –  But you can assert the redirected or forwarded URL •  Also of interest –  HTML Unit / Selenium Driver integration (experimental) –  https://github.com/SpringSource/spring-test-mvc- htmlunit
  42. 42. 42 Useful Option for Debugging Print all details to the console, i.e. System.out mockMvc.perform("/foo") .andDo(print()) .andExpect(status().isOk())
  43. 43. 43 “Standalone” Setup •  No Spring configuration is loaded •  Test one controller at a time •  Just provide the controller instance
  44. 44. 44 “Standalone” Setup Example
  45. 45. 45 Test with Servlet Filters
  46. 46. 46 Re-use Request Props & Expectations
  47. 47. 47 Direct Access to underlying MvcResult
  48. 48. 48 Client-side REST Example
  49. 49. 49 Client-side REST Test Recap •  An instance of RestTemplate configured with custom ClientHttpRequestFactory •  Records and asserts expected requests –  Instead of executing them •  Code using RestTemplate can now be invoked •  Use verify() to assert all expectations were executed
  50. 50. 50 Acknowledgements The Spring MVC Test support draws inspiration from a similar test framework in Spring Web Services.
  51. 51. 51 In Closing…
  52. 52. 52 Special Thanks to… Rossen Stoyanchev … for permitting reuse of his slides on Spring MVC Test!
  53. 53. 53 Spring Resources •  Spring Framework –  http://projects.spring.io/spring-framework •  Spring Forums –  http://forum.spring.io •  Spring JIRA –  http://jira.springsource.org •  Spring on GitHub –  https://github.com/spring-projects/spring-framework
  54. 54. 54 Spring MVC Test Resources •  Blog post –  http://bit.ly/QCKMzh •  Samples –  https://github.com/spring-projects/spring-mvc-showcase –  http://bit.ly/VN1bPw … sample server tests –  http://bit.ly/13koRQP … sample client tests •  Reference documentation –  http://bit.ly/SmUtD6
  55. 55. 55 Blogs •  Swiftmind Team Blog –  http://www.swiftmind.com/blog •  SpringSource Team Blog –  http://spring.io/blog
  56. 56. 56 Q & A Sam Brannen @sam_brannen www.slideshare.net/sbrannen www.swiftmind.com

×