testing with spring 4.x

73
Unless otherwise indicated, these slides are © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Testing with Spring 4.x Sam Brannen @sam_brannen

Upload: sam-brannen

Post on 15-Jul-2015

390 views

Category:

Software


5 download

TRANSCRIPT

Page 1: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense Unless otherwise indicated, these slides are © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense: http://creativecommons.org/licenses/by-nc/3.0/

Testing with Spring 4.x Sam Brannen @sam_brannen

Page 2: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Sam Brannen

•  Spring and Java Consultant @ Swiftmind •  Java Developer for over 15 years

•  Spring Framework Core Committer since 2007 •  Component lead for spring-test

•  Spring Trainer •  Speaker on Spring, Java, and testing

•  Swiss Spring User Group Lead

2

Page 3: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Areas of expertise –  Spring * –  Java EE –  Software Architecture –  Software Engineering Best

Practices

Where you find us •  Zurich, Switzerland •  @swiftmind •  http://www.swiftmind.com

3

Your experts for Spring and Enterprise Java

Page 4: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

A show of hands…

4

?

? ?

?

?

Page 5: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Agenda

•  Deprecations, Pruning, & Dependencies

•  Recap of Testing with Spring 3.x

•  Testing Themes in 4.x

•  Details, Tips, & Examples

•  Q&A

5

Page 6: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Deprecations, Pruning, & Dependencies

6

Page 7: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Spring Cleaning in 4.x

•  All deprecated packages removed

•  Many deprecated methods and fields removed as well

•  Mind the deprecation warnings… before upgrading from 3.x

7

Page 8: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Pruning in 4.0

•  JUnit 3.8 support •  Use JUnit 4 or TestNG

•  @ExpectedException •  Use @Test(expected) or @Rule ExpectedException in JUnit •  Use @Test(expectedExceptions) in TestNG

•  @NotTransactional •  Use @Transactional(propagation=NOT_SUPPORTED)

•  SimpleJdbcTestUtils •  Use JdbcTestUtils, ScriptUtils, or @Sql

8

Page 9: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Dependency Upgrades in 4.0

•  Servlet API mocks •  Now based on Servlet 3.0 •  Servlet 2.5 still supported in production

•  JUnit •  Tested against à 4.11

•  TestNG •  Tested against à 6.8.5

9

Page 10: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Dependency Upgrades in 4.1

•  JUnit •  Minimum version à 4.9 •  Recommended à 4.11

•  TestNG •  Tested against à 6.8.8

10

Page 11: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Testing with Spring 3.x

11

Page 12: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Testing Themes from Spring 3.x (1/2)

•  Embedded databases •  <jdbc:embedded-database /> & <jdbc:initialize-database /> •  EmbeddedDatabaseBuilder & EmbeddedDatabaseFactoryBean

•  @Configuration classes

•  @ActiveProfiles

•  ApplicationContextInitializers

12

Page 13: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Testing Themes from Spring 3.x (2/2)

•  @WebAppConfiguration •  Loading WebApplicationContexts •  Testing request- and session-scoped beans

•  @ContextHierarchy •  Web, Batch, etc.

•  Spring MVC Test framework •  Server-side MVC and REST tests •  Client-side REST tests

13

Page 14: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: Web Integration Test (1/2)

14

@RunWith(SpringJUnit4ClassRunner.class)@WebAppConfiguration@ContextHierarchy({

@ContextConfiguration(classes = RootConfig.class),@ContextConfiguration(classes = WebConfig.class)

})@ActiveProfiles("dev")public class ControllerIntegrationTests { @Autowired private WebApplicationContext wac; private MockMvc mockMvc; // ...

Page 15: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: Web Integration Test (2/2)

15

@Before public void setup() { this.mockMvc = MockMvcBuilders .webAppContextSetup(this.wac).build(); } @Test public void person() throws Exception { this.mockMvc.perform(get("/person/42") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string("{\"name\":\"Sam\"}")); }

Page 16: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Testing Themes in Spring 4.0

16

Page 17: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

New in 4.0 (1/3)

•  SocketUtils •  Scan for available UDP & TCP ports

•  ActiveProfilesResolver API •  Programmatic alternative to static profile strings •  Set via new resolver attribute in @ActiveProfiles

•  Meta-annotation support for tests •  Attribute overrides (optional and required)

17

Page 18: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

New in 4.0 (2/3)

•  New deleteFromTableWhere() method in AbstractTransactional*SpringContextTests

•  * à JUnit4 or TestNG

•  New verify() and reset() methods in AnnotationDrivenStaticEntityMockingControl

•  Multi-line SQL comments: •  ResourceDatabasePopulator, JdbcTestUtils, ScriptUtils

18

Page 19: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

New in 4.0 (3/3)

•  TestContext converted to an interface •  Allows TestContext to be mocked in unit tests

•  Simultaneous use of classes and locations in @ContextConfiguration for hybrid loaders

•  See Spring Boot

•  Servlet API mock improvements

19

Page 20: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Testing Themes in Spring 4.1

20

Page 21: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

New in 4.1 – Context Config

•  Context config with Groovy scripts

•  Declarative configuration for test property sources

•  @TestPropertySource

21

Page 22: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

New in 4.1 – Transactions and SQL

•  Programmatic test transaction management •  TestTransaction API

•  Declarative SQL script execution •  @Sql, @SqlConfig, @SqlGroup

•  Improved docs for transactional tests

22

Page 23: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

New in 4.1 – Bootstrap & TestExecutionListeners

•  TestContext bootstrap strategy •  TestContextBootstrapper & @BootstrapWith

•  Automatic discovery of default TestExecutionListeners •  Uses SpringFactoriesLoader •  Already used by Spring Security

•  Merging custom TestExecutionListeners with defaults •  @TestExecutionListeners(mergeMode=MERGE_WITH_DEFAULTS) •  Defaults to REPLACE_DEFAULTS

23

Page 24: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

New in 4.1 – Spring MVC Test

•  Assert JSON responses with JSON Assert •  Complements JSONPath support

•  Create MockMvcBuilder recipes with MockMvcConfigurer •  Developed to apply Spring Security setup but can be used by anyone

•  AsyncRestTemplate support in MockRestServiceServer •  For asynchronous client-side testing

24

Page 25: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

New in 4.1 – Odds & Ends

•  AssertThrows: refactored to support Throwable

•  Various improvements to Servlet API mocks

25

Page 26: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Details, Tips, & Examples

26

Page 27: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

SocketUtils

•  Utility class introduced in Spring Framework 4.0 •  Located in spring-core •  Can be used in production code •  But ideal for embedded testing scenarios (SMTP, FTP, etc.)

•  Finds available TCP and UDP ports on localhost •  Default port range: 1024 à 65535 •  See Javadoc for all options

•  Straightforward usage in Java and @Configuration classes

27

Page 28: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Using SocketUtils in XML Config

•  Via fully qualified class name and SpEL <bean id="bean1" ... p:port="#{T(org.springframework.util.SocketUtils).findAvailableTcpPort(12000)}" /> •  Via socketUtils bean and SpEL (as of Spring 4.0.8 & 4.1.1) <bean id="socketUtils" class="org.springframework.util.SocketUtils" /><bean id="bean1" ... p:port="#{socketUtils.findAvailableTcpPort(12000)}" /><bean id="bean2" ... p:port="#{socketUtils.findAvailableTcpPort(30000)}" />

28

Page 29: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Tip: Define Free Port as Bean

•  Define the free port as a Spring Bean… <bean id="serverPort" class="java.lang.Integer" c:_="#{T(socketUtils.findAvailableTcpPort()}" />•  Then reference the serverPort from other beans

•  Or inject it into components, @Configuration classes, and tests

29

Page 30: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: @ActiveProfiles – Declarative

30

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration@ActiveProfiles("dev")public class IntegrationTests { // ...}

But what if static isn’t good enough?

Page 31: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: @ActiveProfiles – Programmatic

31

public class MyResolver implements ActiveProfilesResolver { public String[] resolve(Class<?> testClass) { // resolve bean definition profiles for test class }}@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration@ActiveProfiles(resolver = MyProfileResolver.class)public class IntegrationTests { // ...}

Implement custom resolver

And declare it

Page 32: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Composable Stereotypes – Quick Review

•  Combining meta-annotations on a custom stereotype •  Automatically detected: no configuration necessary!

32

Page 33: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Duplicate Test Configuration == Bad

@ContextConfiguration("/test-config.xml")@ActiveProfiles("dev")@Transactionalpublic class OrderRepositoryTests {}@ContextConfiguration("/test-config.xml")@ActiveProfiles("dev")@Transactionalpublic class UserRepositoryTests {}

33

duplication

duplication

Page 34: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Custom Test Annotation == Good

@Target(TYPE)@Retention(RUNTIME)@ContextConfiguration("/test-config.xml")@ActiveProfiles("dev")@Transactionalpublic @interface TransactionalDevTest { }@TransactionalDevTestpublic class OrderRepositoryTests { }@TransactionalDevTestpublic class UserRepositoryTests { }

34

common config

Page 35: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Composable Annotations with Overrides

•  Composable annotations may override attributes of meta-annotations

•  Purely convention-based •  Matched by attribute name and type •  Can lead to potential naming conflicts

•  Cannot override the value attribute

35

Page 36: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Optional Annotation Attribute Override

@Target(TYPE)@Retention(RUNTIME)@ContextConfiguration@Transactionalpublic @interface TransactionalTest {

String[] locations() default "/test-config.xml";}@TransactionalTest(locations = "/order-test-config.xml")public class OrderRepositoryTests { }

36

optional: overrides default

default

locations declared here will be ignored

Page 37: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Required Annotation Attribute Override

@Target(TYPE)@Retention(RUNTIME)@ContextConfiguration@Transactionalpublic @interface TransactionalTest {

String[] locations();}@TransactionalTest(locations = "/order-test-config.xml")public class OrderRepositoryTests { }

37

required

no default

locations declared here will be ignored

Page 38: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Groovy Beans in Spring

•  Spring Framework 4.0 introduced support for the Groovy Bean Definition DSL via the GroovyBeanDefinitionReader and GenericGroovyApplicationContext

•  Spring Framework 4.1 introduces support for Groovy scripts in web applications via the GroovyWebApplicationContext

•  Testing support added in 4.1…

38

Page 39: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Spring Bean Definitions with Groovy DSL

import org.mypackage.domain.Person;

beans { xmlns util: 'http://www.springframework.org/schema/util'

person1(Person) { name = "homer" age = 45 props = [overweight: true, height: "1.8m"] children = ["bart", "lisa"] } util.list(id: 'foo') { value 'one' value 'two' }}

39

Page 40: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Groovy Scripts for Context Config in Tests

•  Spring Framework 4.1 introduces support for Groovy scripts in integration tests via @ContextConfiguration

•  Scripts are configured via the locations or value attribute o  Resource semantics identical to XML o  Default detected with “Context.groovy” suffix in same package

•  The inheritLocations flag is fully supported

•  Groovy and XML configuration can be declared together

•  Groovy WebApplicationContexts supported via @WebAppConfiguration

40

Page 41: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: Groovy Script Config

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("/context.groovy")public class GroovyPersonTests { @Autowired private Person person; /* test methods using person bean */}

41

Page 42: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: Default Groovy Script Detection

public com.example;@RunWith(SpringJUnit4ClassRunner.class)// ApplicationContext will be loaded from// “classpath:com/example/MyTestContext.groovy”@ContextConfigurationpublic class MyTest { /* ... */}

42

Page 43: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: Groovy & XML Config Together

@RunWith(SpringJUnit4ClassRunner.class)// ApplicationContext will be loaded from// “/context.groovy” and “/context.xml”@ContextConfiguration({ "/context.groovy", "/context.xml" })public class MyTest { /* ... */}

43

Page 44: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Test Property Sources

•  Spring 3.1 introduced PropertySources abstraction •  Configured via Environment or via @PropertySource

•  Spring 4.1 supports declarative test property sources •  Configured via @TestPropertySource

•  Test property sources are declared via annotation attributes •  locations or value: resource locations •  properties: inlined properties •  both are inherited by default

44

Page 45: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

@TestPropertySource – locations

•  String array of resource locations for Java Properties files

•  Both traditional *.properties and XML formats are supported

•  Resource semantics are identical to those for locations in @ContextConfiguration

45

Page 46: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: @TestPropertySource – locations

@ContextConfiguration@TestPropertySource("/test.properties")public class MyIntegrationTests {

// class body...}

46

Page 47: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

@TestPropertySource – properties

•  Inlined properties can be declared as key/value pairs

•  Uses syntax for entries in Java properties files: •  "key=value" •  "key:value" •  "key value"

47

Page 48: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: @TestPropertySource – properties

@ContextConfiguration@TestPropertySource( properties = {"foo=bar", "port: 4242"})public class MyIntegrationTests {

// class body...}

48

Page 49: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Default Properties File Detection

•  If neither locations nor properties are defined, a default properties file will be detected

•  Default is detected with “.properties” suffix in same package

•  If the class is com.example.MyTest, the default properties file is “classpath:com/example/MyTest.properties”

•  Exception is thrown if default is not present

49

Page 50: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

@TestPropertySource – Precedence

50

Inlined

Files

Application & System

test

prec

eden

ce

Page 51: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: @TestPropertySource – locations & properties

@ContextConfiguration@TestPropertySource( locations = "/test.properties", properties = "port: 4242")public class MyIntegrationTests {

// class body...}

51

Page 52: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Programmatic Transaction Management in Tests

•  History Lesson: Spring’s JUnit 3.8 testing framework supported endTransaction() and startNewTransaction() methods in AbstractTransactionalSpringContextTests

•  But… the Spring TestContext Framework, introduced in Spring 2.5, did not… until now

•  Due to popular demand, Spring 4.1 introduces a new TestTransaction API

52

Page 53: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Transactions in Spring

•  Spring-managed transactions: managed by Spring in the ApplicationContext

•  @Transactional and AOP

•  Application-managed transactions: managed programmatically within application code

•  TransactionTemplate and TransactionSynchronizationManager

•  Test-managed transactions: managed by the Spring TestContext Framework

•  @Transactional on test classes and test methods •  Transaction is rolled back by default!

53

Page 54: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: Declarative Transaction Management in Tests

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration@Transactionalpublic class TransactionalTests { @Test public void withinTransaction() { /* ... */ }

54

What if we want to stop & start the

transaction within the test method?

Page 55: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

TestTransaction API

•  Static methods for interacting with test-managed transactions

•  isActive() •  isFlaggedForRollback()

•  flagForCommit() •  flagForRollback()

•  end() •  start()

55

query status

change default rollback setting

end: roll back or commit based on flag start: new tx with default rollback setting

Page 56: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: Programmatic Transaction Management in Tests

@Testpublic void withinTransaction() { // assert initial state in test database: assertNumUsers(2); deleteFromTables("user"); // changes to the database will be committed TestTransaction.flagForCommit(); TestTransaction.end(); assertFalse(TestTransaction.isActive()); assertNumUsers(0); TestTransaction.start(); // perform other actions against the database that will // be automatically rolled back after the test completes...}

56

Page 57: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Executing SQL Scripts

57

Page 58: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: Embedded Database in Java Config

58

@Beanpublic DataSource dataSource() { return new EmbeddedDatabaseBuilder() .setType(H2) .setScriptEncoding("UTF-8") .ignoreFailedDrops(true) .addScript("schema.sql") .addScripts("user_data.sql", "country_data.sql") .build();}

API greatly improved in Spring 4.0.3

Page 59: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: Embedded Database in XML Config

<jdbc:embedded-database id="dataSource" type="H2"> <jdbc:script location="classpath:/schema.sql" /> <jdbc:script location="classpath:/user_data.sql" /></jdbc:embedded-database>

59

Page 60: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: Populate Database in XML Config

<jdbc:initialize-database data-source="dataSource"> <jdbc:script location="classpath:/schema_01.sql" /> <jdbc:script location="classpath:/schema_02.sql" /> <jdbc:script location="classpath:/data_01.sql" /> <jdbc:script location="classpath:/data_02.sql" /></jdbc:initialize-database>

60

Page 61: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Executing SQL per Test Method

•  The previous techniques are very useful for setting up the initial database state

•  Q: But how can we execute SQL scripts per test method? •  A: Programmatically via ScriptUtils,

ResourceDatabasePopulator, or abstract transactional base test classes for JUnit and TestNG.

•  Q: OK, but how can we do that declaratively? •  A: Via @Sql in Spring Framework 4.1!

61

Page 62: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Executing SQL Scripts Declaratively with @Sql

•  @Sql: declared on a test class or test method •  method-level overrides class-level

•  The scripts attribute is used to declare resource locations for SQL scripts

•  semantics analogous to locations in @ContextConfiguration

•  Scripts can be executed before or after a test method •  configured via the executionPhase attribute of @Sql

62

Page 63: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Ex: @Sql in Action

@ContextConfiguration@Sql({ "schema1.sql", "data1.sql" })public class SqlScriptsTests { @Test public void classLevelScripts() { /* ... */ } @Test @Sql({ "schema2.sql", "data2.sql" }) public void methodLevelScripts() { /* ... */ }

63

Page 64: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Default SQL Script Detection

•  If no scripts are declared, a default script will be detected •  Depending on where @Sql is declared

•  Class-level: for com.example.DbTest, the default is “classpath:com/example/DbTest.sql”

•  Method-level: for com.example.DbTest.test(), the default is “classpath:com/example/DbTest.test.sql”

•  If the default is not present, an exception is thrown

64

Page 65: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Declaring Multiple @Sql Sets

•  Declare multiple sets of @Sql scripts for varying configuration

•  Java 8: use @Sql as a repeatable annotation

•  Java 6 & 7: wrap @Sql sets in @SqlGroup

65

Page 66: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

@Sql as a Repeatable Annotation (Java 8)

66

@Test@Sql( scripts="/test-schema.sql", config = @SqlConfig(commentPrefix = "`")@Sql("/user-data.sql")public void userTest() { // code that uses the test schema and test data}

Schema uses custom syntax

Page 67: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

@Sql wrapped in @SqlGroup (Java 6 & 7)

67

@Test@SqlGroup({ @Sql( scripts="/test-schema.sql", config = @SqlConfig(commentPrefix = "`"), @Sql("/user-data.sql")})public void userTest() { // code that uses the test schema and test data}

Page 68: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Configuring SQL Scripts with @SqlConfig

•  @SqlConfig: configures script parsing and error handling •  Class-level: serves as global configuration for the test class •  @Sql(config): serves as local configuration for the enclosing @Sql

•  Local configuration inherits global configuration and can selectively override global configuration

•  Transaction management for script execution is configured via the dataSource, transactionManager, and transactionMode attributes

•  See Javadoc and reference manual for details

68

Page 69: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

In closing…

69

Page 70: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Related Sessions @ SpringOne 2GX 2014

70

•  The Quest for the Holy Integration Test •  Ken Krueger and Rob Winch •  September 10, 2014 •  4:30 PM - 6:00 PM

•  Building highly modular and testable business systems with Spring Integration

•  Marius Bogoevici •  September 11, 2014 •  10:30 AM - 12:00 PM

Page 71: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Spring Resources

Spring Framework: http://projects.spring.io/spring-framework Spring Guides: http://spring.io/guides Spring JIRA: https://jira.spring.io

Spring on GitHub: https://github.com/spring-projects/spring-framework Stack Overflow: spring, spring-test, spring-mvc, …

71

Page 72: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Blogs

Spring Blog: http://spring.io/blog Swiftmind Blog: http://www.swiftmind.com/blog

72

Page 73: Testing with Spring 4.x

© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial l icense

Q & A Sam Brannen

@sam_brannen

www.slideshare.net/sbrannen

www.swiftmind.com

73

@springcentral | spring.io/video