spring testing
DESCRIPTION
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 TestsTRANSCRIPT
![Page 1: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/1.jpg)
© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission.
Spring TestingMattias Severson
![Page 2: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/2.jpg)
Agenda
• Basic Spring Testing
• Embedded Database
• Transactions
• Profiles
• Controller Tests
• Server Integration Tests
2
![Page 3: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/3.jpg)
3
Mattias
![Page 4: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/4.jpg)
Bank App
4
![Page 5: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/5.jpg)
AccountService
BankController
ImmutableAccount
AccountEntityAccountRepository
5
Architecture
![Page 6: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/6.jpg)
Basics
6
![Page 7: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/7.jpg)
jUnit Test
public class AccountServiceTest {
AccountService aService;
@Before public void setUp() { aService = new AccountServiceImpl(); }
@Test public void testDoSomething() { aService.doSomething(); // verify ... }}
7
![Page 8: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/8.jpg)
public class AccountServiceTest {
@Autowired AccountService aService;
@Test public void testDoSomething() { aService.doSomething(); // verify ... }}
@Autowired
8
![Page 9: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/9.jpg)
@ContextConfiguration("/application-context.xml")public class AccountServiceTest {
@Autowired AccountService aService;
@Test public void testDoSomething() { aService.doSomething(); // verify ... }}
public class AccountServiceTest {
@Autowired AccountService aService;
@Test public void testDoSomething() { aService.doSomething(); // verify ... }}
9
@ContextConfiguration
![Page 10: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/10.jpg)
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("/application-context.xml")public class AccountServiceTest {
@Autowired AccountService aService;
@Test public void testDoSomething() { aService.doSomething(); // verify ... }}
@ContextConfiguration("/application-context.xml")public class AccountServiceTest {
@Autowired AccountService aService;
@Test public void testDoSomething() { aService.doSomething(); // verify ... }}
10
SpringJUnit4ClassRunner
![Page 11: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/11.jpg)
• Caches ApplicationContext –static memory–unique context configuration–within the same test suite
• All tests execute in the same JVM
11
@ContextConfiguration
![Page 12: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/12.jpg)
• @Before / @After–Mockito.reset(mockObject)–EasyMock.reset(mockObject)
• @DirtiesContext
12
Mocked Beans
![Page 13: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/13.jpg)
Embedded DB
13
AccountRepository AccountEntity
![Page 14: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/14.jpg)
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
![Page 15: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/15.jpg)
Java Config
@Configurationpublic 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
![Page 16: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/16.jpg)
Demo
16
![Page 17: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/17.jpg)
Transactions
17
![Page 18: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/18.jpg)
Tx Test
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("/application-context.xml")public class AccountServiceTest {
@Test public void testDoSomething() { // call DB }
}
@Transactional
@Test public void testDoSomething() { // call DB }
18
![Page 19: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/19.jpg)
Tx Annotations
• @TransactionConfiguration
• @BeforeTransaction
• @AfterTransaction
• @Rollback
19
![Page 20: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/20.jpg)
Avoid False Positives
• Always flush() before validation!
–JPA • entityManager.flush();
–Hibernate• sessionFactory.getCurrentSession().flush();
20
![Page 21: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/21.jpg)
Demo
21
![Page 22: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/22.jpg)
No Transactions?
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("...")public class AccountRepositoryTest {
@Autowired AccountRepository accountRepo;
@Before public void setUp() { accountRepo.deleteAll(); accountRepo.save(testData); }}
22
![Page 23: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/23.jpg)
Spring Profiles
23
![Page 24: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/24.jpg)
XML Profiles
<beans ...>
<bean id="dataSource"> <!-- Test data source --> </bean>
<bean id="dataSource"> <!-- Production data source --> </bean>
</beans>
<beans profile="testProfile">
</beans>
<beans profile="prodProfile">
</beans>
24
![Page 25: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/25.jpg)
Java Config Profile
@Configurationpublic class EmbeddedDbConfig {
@Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder(). // ... }}
@Profile(“testProfile”)
25
![Page 26: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/26.jpg)
Component Profile
@Componentpublic class SomeClass implements SomeInterface {
}
@Profile(“testProfile”)
26
![Page 27: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/27.jpg)
Tests and Profiles
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(“/application-context.xml”)public class SomeTest {
@Autowired SomeClass someClass;
@Test public void testSomething() { ... }}
@ActiveProfiles("testProfile")
27
![Page 28: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/28.jpg)
Demo
28
AccountRepository AccountEntity
AccountService ImmutableAccount
![Page 29: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/29.jpg)
web.xml
<web-app ...>
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
</web-app>
<context-param> <param-name>spring.profiles.active</param-name> <param-value>someProfile</param-value> </context-param>
29
![Page 30: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/30.jpg)
ApplicationContext
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();ctx.getEnvironment().setActiveProfiles("someProfile");ctx.register(SomeConfig.class);ctx.scan("com.jayway.demo");ctx.refresh();
30
![Page 31: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/31.jpg)
Env Property
System.getProperty(“spring.profiles.active”);
mvn -Dspring.profiles.active=testProfile
31
![Page 32: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/32.jpg)
Default Profiles
ctx.getEnvironment().setDefaultProfiles("...");
System.getProperty("spring.profiles.default");
32
<context-param> <param-name>spring.profiles.default</param-name> <param-value>defaultProfile</param-value></context-param>
<beans profile="default"> <!-- default beans --></beans>
@Profile("default")
![Page 33: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/33.jpg)
Profile Alternatives
33
• .properties
• Maven Profile
![Page 34: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/34.jpg)
Test Controller AccountRepository
AccountService
AccountEntity
ImmutableAccount
BankController
34
![Page 35: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/35.jpg)
Spring MVC Test Framework
• Call Controllers through DispatcherServlet
• MockHttpServletRequest• MockHttpServletResponse
35
![Page 36: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/36.jpg)
MockMvc
MockMvc mockMvc = MockMvcBuilders .standaloneSetup(new BankController()) .build();
36
MockMvc mockMvc = MockMvcBuilders .standaloneSetup(new BankController()) .setMessageConverters(...) .setValidator(...) .setConversionService(...) .addInterceptors(...) .setViewResolvers(...) .setLocaleResolver(...) .addFilter(...) .build();
![Page 37: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/37.jpg)
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
![Page 38: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/38.jpg)
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("/application-context.xml")@WebAppConfigurationpublic class WebApplicationTest {
@Autowired WebApplicationContext wac;
MockMvc mockMvc;
@Before public void setup() { mockMvc = MockMvcBuilders .webAppContextSetup(wac) .build(); }
38
![Page 39: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/39.jpg)
Demo
39
![Page 40: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/40.jpg)
Testing Views
• Supported templates–JSON–XML–Velocity–Thymeleaf
• Except JSP
40
![Page 41: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/41.jpg)
Server Integration Tests
41
![Page 42: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/42.jpg)
appCtx
Spring Integration Test
42
Embedded DB
txMngr
test
dataSrc
![Page 43: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/43.jpg)
App Server
appCtx
Server Integration Test
43
Embedded DB
txMngr
test
dataSrc
HTTP
![Page 44: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/44.jpg)
App Server
App Server
44
appCtx
DB
txMngrdataSrc
testAppCtx
dataSrc
testHTTP
![Page 45: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/45.jpg)
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
![Page 46: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/46.jpg)
maven-failsafe-plugin
**/IT*.java**/*IT.java**/*ITCase.java
46
![Page 47: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/47.jpg)
Test RESTful API
47
• RestTemplate• Selenium• HttpClient• ...
![Page 48: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/48.jpg)
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
![Page 49: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/49.jpg)
Demo
49
![Page 50: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/50.jpg)
Questions?
50
![Page 51: Spring Testing](https://reader033.vdocument.in/reader033/viewer/2022052618/554f4a9cb4c905423f8b4c96/html5/thumbnails/51.jpg)
Learn More. Stay Connected.
Talk to us on Twitter: @springcentralFind session replays on YouTube: spring.io/video
@mattiasseverson
http://blog.jayway.com/author/mattiasseverson/