Spring Testing
Mattias Severson

© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission.
Agenda
•
•
•
•
•
•
2

Basic Spring Testing
Embedded Database
Transactions
Profiles
Controller Tests
Server Integration Test...
Mattias

3
Bank App

4
Architecture
BankController

AccountService

AccountRepository

5

ImmutableAccount

AccountEntity
Basics

6
jUnit Test
public class AccountServiceTest {
AccountService aService;
@Before
public void setUp() {
aService = new Account...
@Autowired

public class AccountServiceTest {
@Autowired
AccountService aService;
@Test
public void testDoSomething() {
aS...
@ContextConfiguration

@ContextConfiguration("/application-context.xml")
public class AccountServiceTest {
@Autowired
Acco...
SpringJUnit4ClassRunner
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/application-context.xml")
public c...
@ContextConfiguration

• Caches ApplicationContext
–static memory
–unique context configuration
–within the same test suit...
Mocked Beans

• @Before / @After
–Mockito.reset(mockObject)
–EasyMock.reset(mockObject)

• @DirtiesContext

12
Embedded DB

13

AccountRepository

AccountEntity
XML Config

<jdbc:embedded-database id="dataSource" type="HSQL">
<jdbc:script location="classpath:db-schema.sql"/>
<jdbc:s...
Java Config
@Configuration
public class EmbeddedDbConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatab...
Demo

16
Transactions

17
Tx Test

@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/application-context.xml")
public c...
Tx Annotations

•
•
•
•

19

@TransactionConfiguration
@BeforeTransaction
@AfterTransaction
@Rollback
Avoid False Positives
• Always flush() before validation!
–JPA
• entityManager.flush();

–Hibernate
• sessionFactory.getCu...
Demo

21
No Transactions?
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("...")
public class AccountRepositoryTest {...
Spring Profiles

23
XML Profiles
<beans ...>
<beans profile="testProfile">
<bean id="dataSource">
<!-- Test data source -->
</bean>
</beans>
<...
Java Config Profile
@Profile(“testProfile”)
@Configuration
public class EmbeddedDbConfig {
@Bean
public DataSource dataSou...
Component Profile

@Profile(“testProfile”)
@Component
public class SomeClass implements SomeInterface {
}

26
Tests and Profiles
@ActiveProfiles("testProfile")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“/applicat...
AccountService

Demo

28

ImmutableAccount

AccountRepository

AccountEntity
web.xml
<web-app ...>
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>someProfile</param-valu...
ApplicationContext

AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext();
ctx.getEnvironment(...
Env Property

System.getProperty(“spring.profiles.active”);
mvn -Dspring.profiles.active=testProfile

31
Default Profiles
System.getProperty("spring.profiles.default");
ctx.getEnvironment().setDefaultProfiles("...");
<context-p...
Profile Alternatives

• .properties
• Maven Profile

33
BankController

AccountService

Test Controller

34

ImmutableAccount

AccountRepository

AccountEntity
Spring MVC Test Framework

• Call Controllers through DispatcherServlet
• MockHttpServletRequest
• MockHttpServletResponse...
MockMvc

MockMvc mockMvc = MockMvcBuilders
.standaloneSetup(new BankController())
.setMessageConverters(...)
.build();
.se...
Assertions

mockMvc.perform(get("/url")
.accept(MediaType.APPLICATION_XML))
.andExpect(response().status().isOk())
.andExp...
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/application-context.xml")
@WebAppConf...
Demo

39
Testing Views
• Supported templates
–JSON
–XML
–Velocity
–Thymeleaf

• Except JSP

40
Server Integration Tests

41
Spring Integration Test
appCtx
dataSrc
test
Embedded
DB

42

txMngr
Server Integration Test
App Server
appCtx
dataSrc
test

HTTP
Embedded
DB

43

txMngr
App Server
App Server
appCtx
test

HTTP

dataSrc

testAppCtx
dataSrc

44

DB

txMngr
jetty-maven-plugin
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</go...
maven-failsafe-plugin

**/IT*.java
**/*IT.java
**/*ITCase.java

46
Test RESTful API

• RestTemplate
• Selenium
• HttpClient
• ...

47
REST Assured
@Test
public void shouldGetSingleAccount() {
expect().
statusCode(HttpStatus.SC_OK).
contentType(ContentType....
Demo

49
Questions?

50
Learn More. Stay Connected.

@mattiasseverson
http://blog.jayway.com/author/mattiasseverson/

Talk to us on Twitter: @spri...
Upcoming SlideShare
Loading in …5
×

Spring Testing

1,383 views

Published on

Speaker: Mattias Severson
Is it possible to decrease the turn-around time of your test suite? How can you make sure that your tests execute independently? Is it possible to automatically verify that the database schema is kept in sync with the source code? What are the trade-offs? In this presentation, you will learn how to apply features such as the Spring MVC Test Framework, Spring profiles, and embedded databases, to automate and improve your test suite, thus improving the overall quality of your project. A simplistic Spring web app will be used to show some practical code examples.
Topics include:
Basic Spring Testing
Embedded Database
Transactions
Profiles
Controller Tests
Server Integration Tests

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,383
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
61
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Spring Testing

  1. 1. Spring Testing Mattias Severson © 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission.
  2. 2. Agenda • • • • • • 2 Basic Spring Testing Embedded Database Transactions Profiles Controller Tests Server Integration Tests
  3. 3. Mattias 3
  4. 4. Bank App 4
  5. 5. Architecture BankController AccountService AccountRepository 5 ImmutableAccount AccountEntity
  6. 6. Basics 6
  7. 7. jUnit Test public class AccountServiceTest { AccountService aService; @Before public void setUp() { aService = new AccountServiceImpl(); } @Test public void testDoSomething() { aService.doSomething(); // verify ... } } 7
  8. 8. @Autowired public class AccountServiceTest { @Autowired AccountService aService; @Test public void testDoSomething() { aService.doSomething(); // verify ... } } 8
  9. 9. @ContextConfiguration @ContextConfiguration("/application-context.xml") public class AccountServiceTest { @Autowired AccountService aService; @Test public void testDoSomething() { aService.doSomething(); // verify ... } } 9
  10. 10. SpringJUnit4ClassRunner @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/application-context.xml") public class AccountServiceTest { @Autowired AccountService aService; @Test public void testDoSomething() { aService.doSomething(); // verify ... } } 10
  11. 11. @ContextConfiguration • Caches ApplicationContext –static memory –unique context configuration –within the same test suite • All tests execute in the same JVM 11
  12. 12. Mocked Beans • @Before / @After –Mockito.reset(mockObject) –EasyMock.reset(mockObject) • @DirtiesContext 12
  13. 13. Embedded DB 13 AccountRepository AccountEntity
  14. 14. XML Config <jdbc:embedded-database id="dataSource" type="HSQL"> <jdbc:script location="classpath:db-schema.sql"/> <jdbc:script location="classpath:db-test-data.sql"/> </jdbc:embedded-database> 14
  15. 15. Java Config @Configuration public class EmbeddedDbConfig { @Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.HSQL) .addScript(“classpath:db-schema.sql”) .addScript(“classpath:db-test-data.sql”) .build(); } } 15
  16. 16. Demo 16
  17. 17. Transactions 17
  18. 18. Tx Test @Transactional @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/application-context.xml") public class AccountServiceTest { @Test public void testDoSomething() { // call DB } } 18
  19. 19. Tx Annotations • • • • 19 @TransactionConfiguration @BeforeTransaction @AfterTransaction @Rollback
  20. 20. Avoid False Positives • Always flush() before validation! –JPA • entityManager.flush(); –Hibernate • sessionFactory.getCurrentSession().flush(); 20
  21. 21. Demo 21
  22. 22. No Transactions? @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("...") public class AccountRepositoryTest { @Autowired AccountRepository accountRepo; @Before public void setUp() { accountRepo.deleteAll(); accountRepo.save(testData); } } 22
  23. 23. Spring Profiles 23
  24. 24. XML Profiles <beans ...> <beans profile="testProfile"> <bean id="dataSource"> <!-- Test data source --> </bean> </beans> <beans profile="prodProfile"> <bean id="dataSource"> <!-- Production data source --> </bean> </beans> </beans> 24
  25. 25. Java Config Profile @Profile(“testProfile”) @Configuration public class EmbeddedDbConfig { @Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder(). // ... } } 25
  26. 26. Component Profile @Profile(“testProfile”) @Component public class SomeClass implements SomeInterface { } 26
  27. 27. Tests and Profiles @ActiveProfiles("testProfile") @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(“/application-context.xml”) public class SomeTest { @Autowired SomeClass someClass; @Test public void testSomething() { ... } } 27
  28. 28. AccountService Demo 28 ImmutableAccount AccountRepository AccountEntity
  29. 29. web.xml <web-app ...> <context-param> <param-name>spring.profiles.active</param-name> <param-value>someProfile</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app> 29
  30. 30. ApplicationContext AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.getEnvironment().setActiveProfiles("someProfile"); ctx.register(SomeConfig.class); ctx.scan("com.jayway.demo"); ctx.refresh(); 30
  31. 31. Env Property System.getProperty(“spring.profiles.active”); mvn -Dspring.profiles.active=testProfile 31
  32. 32. Default Profiles System.getProperty("spring.profiles.default"); ctx.getEnvironment().setDefaultProfiles("..."); <context-param> <param-name>spring.profiles.default</param-name> <param-value>defaultProfile</param-value> </context-param> @Profile("default") <beans profile="default"> <!-- default beans --> </beans> 32
  33. 33. Profile Alternatives • .properties • Maven Profile 33
  34. 34. BankController AccountService Test Controller 34 ImmutableAccount AccountRepository AccountEntity
  35. 35. Spring MVC Test Framework • Call Controllers through DispatcherServlet • MockHttpServletRequest • MockHttpServletResponse 35
  36. 36. MockMvc MockMvc mockMvc = MockMvcBuilders .standaloneSetup(new BankController()) .setMessageConverters(...) .build(); .setValidator(...) .setConversionService(...) .addInterceptors(...) .setViewResolvers(...) .setLocaleResolver(...) .addFilter(...) .build(); 36
  37. 37. Assertions mockMvc.perform(get("/url") .accept(MediaType.APPLICATION_XML)) .andExpect(response().status().isOk()) .andExpect(content().contentType(“MediaType.APPLICATION_XML”)) .andExpect(xpath(“key”).string(“value”)) .andExpect(redirectedUrl(“url”)) .andExpect(model().attribute(“name”, value)); 37
  38. 38. @WebAppConfiguration @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/application-context.xml") @WebAppConfiguration public class WebApplicationTest { @Autowired WebApplicationContext wac; MockMvc mockMvc; @Before public void setup() { mockMvc = MockMvcBuilders .webAppContextSetup(wac) .build(); } 38
  39. 39. Demo 39
  40. 40. Testing Views • Supported templates –JSON –XML –Velocity –Thymeleaf • Except JSP 40
  41. 41. Server Integration Tests 41
  42. 42. Spring Integration Test appCtx dataSrc test Embedded DB 42 txMngr
  43. 43. Server Integration Test App Server appCtx dataSrc test HTTP Embedded DB 43 txMngr
  44. 44. App Server App Server appCtx test HTTP dataSrc testAppCtx dataSrc 44 DB txMngr
  45. 45. jetty-maven-plugin <executions> <execution> <id>start-jetty</id> <phase>pre-integration-test</phase> <goals> <goal>run</goal> </goals> </execution> <execution> <id>stop-jetty</id> <phase>post-integration-test</phase> <goals> <goal>stop</goal> </goals> </execution> </executions> 45
  46. 46. maven-failsafe-plugin **/IT*.java **/*IT.java **/*ITCase.java 46
  47. 47. Test RESTful API • RestTemplate • Selenium • HttpClient • ... 47
  48. 48. REST Assured @Test public void shouldGetSingleAccount() { expect(). statusCode(HttpStatus.SC_OK). contentType(ContentType.JSON). body("accountNumber", is(1)). body("balance", is(100)). when(). get("/account/1"); } 48
  49. 49. Demo 49
  50. 50. Questions? 50
  51. 51. Learn More. Stay Connected. @mattiasseverson http://blog.jayway.com/author/mattiasseverson/ Talk to us on Twitter: @springcentral Find session replays on YouTube: spring.io/video

×