testing web apps with spring framework 3.2

51
© 2012 SpringSource, by VMware. All rights reserved Testing Web Applications with Spring 3.2 Sam Brannen, Swiftmind, @sam_brannen Rossen Stoyanchev, VMware, @rstoya05

Upload: rossen-stoyanchev

Post on 10-May-2015

6.601 views

Category:

Technology


5 download

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.

TRANSCRIPT

Page 1: Testing Web Apps with Spring Framework 3.2

© 2012 SpringSource, by VMware. All rights reserved

Testing Web Applications with Spring 3.2

Sam Brannen, Swiftmind, @sam_brannen

Rossen Stoyanchev, VMware, @rstoya05

Page 2: Testing Web Apps with Spring Framework 3.2

22

Today's Speakers

Page 3: Testing Web Apps with Spring Framework 3.2

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

Page 4: Testing Web Apps with Spring Framework 3.2

444

Spring Framework core committer

Focus on Spring Web

Main developer of Spring MVC Test

Rossen Stoyanchev

Page 5: Testing Web Apps with Spring Framework 3.2

555

Spring TestContext Framework Updates

Spring MVC Test Framework

Q & A

Agenda

Page 6: Testing Web Apps with Spring Framework 3.2

66

Spring TestContext Framework Updates

Page 7: Testing Web Apps with Spring Framework 3.2

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?

Page 8: Testing Web Apps with Spring Framework 3.2

888

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

A: Just annotate your test class with @WebAppConfiguration!

Loading a WebApplicationContext

Page 9: Testing Web Apps with Spring Framework 3.2

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

Page 10: Testing Web Apps with Spring Framework 3.2

101010

Example: @WebAppConfiguration

Page 11: Testing Web Apps with Spring Framework 3.2

111111

Example: @WebAppConfiguration

Page 12: Testing Web Apps with Spring Framework 3.2

121212

Example: @WebAppConfiguration

Page 13: Testing Web Apps with Spring Framework 3.2

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

Page 14: Testing Web Apps with Spring Framework 3.2

141414

Example: Injecting Mocks

Page 15: Testing Web Apps with Spring Framework 3.2

151515

request: lifecycle tied to the current HttpServletRequest

session: lifecycle tied to the current HttpSession

Web Scopes – Review

Page 16: Testing Web Apps with Spring Framework 3.2

161616

Example: Request-scoped Bean Test

Page 17: Testing Web Apps with Spring Framework 3.2

171717

Example: Request-scoped Bean Config

Page 18: Testing Web Apps with Spring Framework 3.2

181818

Example: Session-scoped Bean Test

Page 19: Testing Web Apps with Spring Framework 3.2

191919

Example: Session-scoped Bean Config

Page 20: Testing Web Apps with Spring Framework 3.2

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

Page 21: Testing Web Apps with Spring Framework 3.2

212121

Example: Multiple Initializers

Page 22: Testing Web Apps with Spring Framework 3.2

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

Page 23: Testing Web Apps with Spring Framework 3.2

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

Page 24: Testing Web Apps with Spring Framework 3.2

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 (!)

Page 25: Testing Web Apps with Spring Framework 3.2

252525

Single Test with Context Hierarchy

Page 26: Testing Web Apps with Spring Framework 3.2

262626

Class and Context Hierarchies

Page 27: Testing Web Apps with Spring Framework 3.2

2727

Built-in Spring MVC Test Support

Page 28: Testing Web Apps with Spring Framework 3.2

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

Page 29: Testing Web Apps with Spring Framework 3.2

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

Page 30: Testing Web Apps with Spring Framework 3.2

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

Page 31: Testing Web Apps with Spring Framework 3.2

313131

Server-Side Example

Page 32: Testing Web Apps with Spring Framework 3.2

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

Page 33: Testing Web Apps with Spring Framework 3.2

333333

Actual Spring MVC configuration loaded

MockHttpServletRequest prepared

Executed via DispatcherServlet

Assertions applied on the resulting MockHttpServletResponse

Server-Side Test Recap

Page 34: Testing Web Apps with Spring Framework 3.2

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?

Page 35: Testing Web Apps with Spring Framework 3.2

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

Page 36: Testing Web Apps with Spring Framework 3.2

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

Page 37: Testing Web Apps with Spring Framework 3.2

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?

Page 38: Testing Web Apps with Spring Framework 3.2

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?

Page 39: Testing Web Apps with Spring Framework 3.2

393939

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

mockMvc.perform("/foo")

.andDo(print())

.andExpect(status().Ok())

Useful Option For Debugging

Page 40: Testing Web Apps with Spring Framework 3.2

404040

No Spring configuration is loaded

Test one controller at a time

Just provide the controller instance

“Standalone” Setup

Page 41: Testing Web Apps with Spring Framework 3.2

414141

“Standalone” Setup Example

Page 42: Testing Web Apps with Spring Framework 3.2

424242

Tests with Servlet Filters

Page 43: Testing Web Apps with Spring Framework 3.2

434343

Re-use Request Properties and Expectations

Page 44: Testing Web Apps with Spring Framework 3.2

444444

Direct Access to the Underlying MvcResult

Page 45: Testing Web Apps with Spring Framework 3.2

454545

Client-Side REST Example

Page 46: Testing Web Apps with Spring Framework 3.2

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

Page 47: Testing Web Apps with Spring Framework 3.2

474747

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

Acknowledgements

Page 48: Testing Web Apps with Spring Framework 3.2

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

Page 49: Testing Web Apps with Spring Framework 3.2

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

Page 50: Testing Web Apps with Spring Framework 3.2

505050

SpringSource Team Blog

• http://blog.springsource.com/

Swiftmind Team Blog

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

Blogs

Page 51: Testing Web Apps with Spring Framework 3.2

515151

Q & A

Sam Brannen

• twitter: @sam_brannen

• www.slideshare.net/sbrannen

• www.swiftmind.com

Rossen Stoyanchev

• twitter: @rstoya05