spring testing

51
© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission. Spring Testing Mattias Severson

Upload: spring-io

Post on 10-May-2015

735 views

Category:

Technology


0 download

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 Tests

TRANSCRIPT

Page 1: Spring Testing

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

Spring TestingMattias Severson

Page 2: Spring Testing

Agenda

• Basic Spring Testing

• Embedded Database

• Transactions

• Profiles

• Controller Tests

• Server Integration Tests

2

Page 3: Spring Testing

3

Mattias

Page 4: Spring Testing

Bank App

4

Page 5: Spring Testing

AccountService

BankController

ImmutableAccount

AccountEntityAccountRepository

5

Architecture

Page 6: Spring Testing

Basics

6

Page 7: Spring Testing

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

public class AccountServiceTest {

@Autowired AccountService aService;

@Test public void testDoSomething() { aService.doSomething(); // verify ... }}

@Autowired

8

Page 9: Spring Testing

@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

@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

• 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

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

• @DirtiesContext

12

Mocked Beans

Page 13: Spring Testing

Embedded DB

13

AccountRepository AccountEntity

Page 14: Spring Testing

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

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

Demo

16

Page 17: Spring Testing

Transactions

17

Page 18: Spring Testing

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

Tx Annotations

• @TransactionConfiguration

• @BeforeTransaction

• @AfterTransaction

• @Rollback

19

Page 20: Spring Testing

Avoid False Positives

• Always flush() before validation!

–JPA • entityManager.flush();

–Hibernate• sessionFactory.getCurrentSession().flush();

20

Page 21: Spring Testing

Demo

21

Page 22: Spring Testing

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

Spring Profiles

23

Page 24: Spring Testing

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

Java Config Profile

@Configurationpublic class EmbeddedDbConfig {

@Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder(). // ... }}

@Profile(“testProfile”)

25

Page 26: Spring Testing

Component Profile

@Componentpublic class SomeClass implements SomeInterface {

}

@Profile(“testProfile”)

26

Page 27: Spring Testing

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

Demo

28

AccountRepository AccountEntity

AccountService ImmutableAccount

Page 29: Spring Testing

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

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

Env Property

System.getProperty(“spring.profiles.active”);

mvn -Dspring.profiles.active=testProfile

31

Page 32: Spring Testing

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

Profile Alternatives

33

• .properties

• Maven Profile

Page 34: Spring Testing

Test Controller AccountRepository

AccountService

AccountEntity

ImmutableAccount

BankController

34

Page 35: Spring Testing

Spring MVC Test Framework

• Call Controllers through DispatcherServlet

• MockHttpServletRequest• MockHttpServletResponse

35

Page 36: Spring Testing

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

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

@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

Demo

39

Page 40: Spring Testing

Testing Views

• Supported templates–JSON–XML–Velocity–Thymeleaf

• Except JSP

40

Page 41: Spring Testing

Server Integration Tests

41

Page 42: Spring Testing

appCtx

Spring Integration Test

42

Embedded DB

txMngr

test

dataSrc

Page 43: Spring Testing

App Server

appCtx

Server Integration Test

43

Embedded DB

txMngr

test

dataSrc

HTTP

Page 44: Spring Testing

App Server

App Server

44

appCtx

DB

txMngrdataSrc

testAppCtx

dataSrc

testHTTP

Page 45: Spring Testing

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

maven-failsafe-plugin

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

46

Page 47: Spring Testing

Test RESTful API

47

• RestTemplate• Selenium• HttpClient• ...

Page 48: Spring Testing

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

Demo

49

Page 50: Spring Testing

Questions?

50

Page 51: Spring Testing

Learn More. Stay Connected.

Talk to us on Twitter: @springcentralFind session replays on YouTube: spring.io/video

@mattiasseverson

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