Testing Web Apps with Spring Framework 3.2

Preview:

DESCRIPTION

Presented on Feb 21, 2013 as part of a springsource.org webinar. A video of the presentation will be available 2 weeks later at http://www.youtube.com/springsourcedev.

Citation preview

© 2012 SpringSource, by VMware. All rights reserved

Testing Web Applications with Spring 3.2

Sam Brannen, Swiftmind, @sam_brannen

Rossen Stoyanchev, VMware, @rstoya05

22

Today's Speakers

333

Spring and Java Consultant @ Swiftmind

Developing Java for over 15 years

Spring Framework Core Committer since 2007

Spring Trainer

Presenter on Spring, Java, OSGi, and testing

Sam Brannen

444

Spring Framework core committer

Focus on Spring Web

Main developer of Spring MVC Test

Rossen Stoyanchev

555

Spring TestContext Framework Updates

Spring MVC Test Framework

Q & A

Agenda

66

Spring TestContext Framework Updates

777

Upgraded to JUnit 4.11 and TestNG 6.5.2

Loading WebApplicationContexts

Testing request- and session-scoped beans

Support for ApplicationContextInitializers

Loading context hierarchies (3.2.1)

And more… (see presentation from SpringOne 2GX 2012)

What's New in the Spring TCF?

888

Q: How do you tell the TestContext Framework to load a WebApplicationContext?

A: Just annotate your test class with @WebAppConfiguration!

Loading a WebApplicationContext

999

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 classpath resources

• The classpath: prefix is also supported

@WebAppConfiguration

101010

Example: @WebAppConfiguration

111111

Example: @WebAppConfiguration

121212

Example: @WebAppConfiguration

131313

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

ServletTestExecutionListener

141414

Example: Injecting Mocks

151515

request: lifecycle tied to the current HttpServletRequest

session: lifecycle tied to the current HttpSession

Web Scopes – Review

161616

Example: Request-scoped Bean Test

171717

Example: Request-scoped Bean Config

181818

Example: Session-scoped Bean Test

191919

Example: Session-scoped Bean Config

202020

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

ApplicationContextInitializer

212121

Example: Multiple Initializers

222222

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

Using Initializers in Tests

232323

Currently only flat, non-hierarchical contexts are supported in tests.

There’s 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?!

Application Context Hierarchies

242424

New @ContextHierarchy annotation

• used in conjunction with @ContextConfiguration

@ContextConfiguration now supports a ‘name’ attribute

• for merging and overriding hierarchy configuration

Testing Context Hierarchies in version 3.2.2 (!)

252525

Single Test with Context Hierarchy

262626

Class and Context Hierarchies

2727

Built-in Spring MVC Test Support

282828

Dedicated support for testing Spring MVC applications

Fluent API

Very easy to write

Includes client and server-side support

Servlet container not required

Overview

292929

Included in spring-test module of Spring Framework 3.2

Builds on

• TestContext framework for loading Spring MVC configuration

• MockHttpServletRequest/Response and other “mock” types

Server-side tests involve DispatcherServlet

Client-side REST testing for code using RestTemplate

In More Detail

303030

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

Spring MVC Test History

313131

Server-Side Example

323232

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

A Note On Fluent API Usage

333333

Actual Spring MVC configuration loaded

MockHttpServletRequest prepared

Executed via DispatcherServlet

Assertions applied on the resulting MockHttpServletResponse

Server-Side Test Recap

343434

Mock request/response types, no Servlet container

However..

• DispatcherServlet + actual Spring MVC configuration used

Hence..

• Not full end-to-end testing, i.e. 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!

Integration Or Unit Testing?

353535

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. database tests

Strategy For Testing

363636

Since we're loading actual Spring MVC config

Need to declare mock dependencies

<bean class="org.mockito.Mockito" factory-method="mock">

<constructor-arg value="org.example.FooDao"/>

</bean>

Then simply inject the mock instance into the test class

• Via @Autowired

• Set up and reset via @Before, @Test, and @After methods

Declaring A Mock Dependency

373737

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

What Can Be Tested?

383838

All view templating technologies will work

• Freemarker/Velocity, Thymeleaf, JSON, XML, PDF, etc.

Except for JSPs (no Servlet container!)

• You can however assert the selected JSP

No redirecting and forwarding

• You can however assert the redirected or forwarded URL

Also of interest

• HTML Unit / Selenium Driver integration (experimental)

• https://github.com/SpringSource/spring-test-mvc-htmlunit

What About the View Layer?

393939

Print all details to the console, i.e. System.out

mockMvc.perform("/foo")

.andDo(print())

.andExpect(status().Ok())

Useful Option For Debugging

404040

No Spring configuration is loaded

Test one controller at a time

Just provide the controller instance

“Standalone” Setup

414141

“Standalone” Setup Example

424242

Tests with Servlet Filters

434343

Re-use Request Properties and Expectations

444444

Direct Access to the Underlying MvcResult

454545

Client-Side REST Example

464646

An instance of RestTemplate configured with custom ClientHttpRequestFactory

Records and asserts expected requests

• Instead of executing them

Code using RestTemlpate can now be invoked

Use verify() to assert all expectations were executed

Client-Side REST Test Recap

474747

The Spring MVC Test support draws inspiration from similar test framework in Spring Web Services

Acknowledgements

484848

Reference doc chapter on Spring MVC Test

Sample tests in the framework source code

• https://github.com/SpringSource/spring-framework/tree/3.2.x/spring-test-mvc/src/test/java/org/springframework/test/web/servlet/samples

• https://github.com/SpringSource/spring-framework/tree/3.2.x/spring-test-mvc/src/test/java/org/springframework/test/web/client/samples

Tests in spring-mvc-showcase

• https://github.com/SpringSource/spring-mvc-showcase

Further Resources: Spring MVC Test

494949

Spring Framework

• http://www.springsource.org/spring-framework

• Reference manual and Javadoc

Forums

• http://forum.springframework.org

JIRA

• http://jira.springframework.org

GitHub

• https://github.com/SpringSource/spring-framework

Further Resources Cont'd

505050

SpringSource Team Blog

• http://blog.springsource.com/

Swiftmind Team Blog

• http://www.swiftmind.com/blog/

Blogs

515151

Q & A

Sam Brannen

• twitter: @sam_brannen

• www.slideshare.net/sbrannen

• www.swiftmind.com

Rossen Stoyanchev

• twitter: @rstoya05

Recommended