Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Unless otherwise indicated...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Sam Brannen
•  Spring and ...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Areas of expertise
–  Spri...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
A show of hands…
4
?
?
?
?...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Agenda
•  Deprecations, Pr...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Deprecations, Pruning, & D...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Spring Cleaning in 4.x
•  ...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Pruning in 4.0
•  JUnit 3....
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Dependency Upgrades in 4.0...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Dependency Upgrades in 4.1...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Testing with Spring 3.x
11
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Testing Themes from Spring...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Testing Themes from Spring...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: Web Integration Test (...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: Web Integration Test (...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Testing Themes in Spring 4...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
New in 4.0 (1/3)
•  Socket...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
New in 4.0 (2/3)
•  New de...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
New in 4.0 (3/3)
•  TestCo...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Testing Themes in Spring 4...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
New in 4.1 – Context Confi...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
New in 4.1 – Transactions ...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
New in 4.1 – Bootstrap & T...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
New in 4.1 – Spring MVC Te...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
New in 4.1 – Odds & Ends
•...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Details, Tips, & Examples
...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
SocketUtils
•  Utility cla...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Using SocketUtils in XML C...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Tip: Define Free Port as B...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: @ActiveProfiles – Decl...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: @ActiveProfiles – Prog...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Composable Stereotypes – Q...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Duplicate Test Configurati...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Custom Test Annotation == ...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Composable Annotations wit...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Optional Annotation Attrib...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Required Annotation Attrib...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Groovy Beans in Spring
•  ...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Spring Bean Definitions wi...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Groovy Scripts for Context...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: Groovy Script Config
@...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: Default Groovy Script ...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: Groovy & XML Config To...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Test Property Sources
•  S...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
@TestPropertySource – loca...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: @TestPropertySource – ...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
@TestPropertySource – prop...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: @TestPropertySource – ...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Default Properties File De...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
@TestPropertySource – Prec...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: @TestPropertySource – ...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Programmatic Transaction M...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Transactions in Spring
•  ...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: Declarative Transactio...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
TestTransaction API
•  Sta...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: Programmatic Transacti...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Executing SQL Scripts
57
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: Embedded Database in J...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: Embedded Database in X...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: Populate Database in X...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Executing SQL per Test Met...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Executing SQL Scripts Decl...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Ex: @Sql in Action
@Contex...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Default SQL Script Detecti...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Declaring Multiple @Sql Se...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
@Sql as a Repeatable Annot...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
@Sql wrapped in @SqlGroup ...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Configuring SQL Scripts wi...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
In closing…
69
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Related Sessions @ SpringO...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Spring Resources
Spring Fr...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Blogs
Spring Blog: http://...
© 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license
Q & A
Sam Brannen
@sam_bra...
Upcoming SlideShare
Loading in …5
×

Testing with Spring 4.x

1,007 views

Published on

The Spring Framework has undergone a lot of innovation in the 4.0 and 4.1 releases, and so has its testing support. Join Spring Test component lead Sam Brannen in this talk to discover what's new in Spring's testing support in 4.0 through 4.1.

This talk will provide attendees an overview of what's been deprecated, what's changed, and what's been introduced in Spring's testing support over the last two years, with real life examples and tips for best practices. Highlights include using SocketUtils to scan for free TCP & UDP server ports, the ActiveProfilesResolver API, meta-annotation support for test annotations including attribute overrides, best practices with TestNG, using Groovy scripts to configure an ApplicationContext for integration tests, improvements to SQL script execution and embedded databases, the new TestContext framework bootstrap strategy, programmatic transaction management in tests, and more.

Published in: Software
  • Be the first to comment

Testing with Spring 4.x

  1. 1. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  2. 2. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  3. 3. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  4. 4. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license A show of hands… 4 ? ? ? ? ?
  5. 5. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Agenda •  Deprecations, Pruning, & Dependencies •  Recap of Testing with Spring 3.x •  Testing Themes in 4.x •  Details, Tips, & Examples •  Q&A 5
  6. 6. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Deprecations, Pruning, & Dependencies 6
  7. 7. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  8. 8. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  9. 9. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  10. 10. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Dependency Upgrades in 4.1 •  JUnit •  Minimum version à 4.9 •  Recommended à 4.11 •  TestNG •  Tested against à 6.8.8 10
  11. 11. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Testing with Spring 3.x 11
  12. 12. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Testing Themes from Spring 3.x (1/2) •  Embedded databases •  <jdbc:embedded-database /> & <jdbc:initialize-database /> •  EmbeddedDatabaseBuilder & EmbeddedDatabaseFactoryBean •  @Configuration classes •  @ActiveProfiles •  ApplicationContextInitializers 12
  13. 13. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  14. 14. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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; // ...
  15. 15. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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"}")); }
  16. 16. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Testing Themes in Spring 4.0 16
  17. 17. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  18. 18. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  19. 19. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  20. 20. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Testing Themes in Spring 4.1 20
  21. 21. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license New in 4.1 – Context Config •  Context config with Groovy scripts •  Declarative configuration for test property sources •  @TestPropertySource 21
  22. 22. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  23. 23. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  24. 24. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  25. 25. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license New in 4.1 – Odds & Ends •  AssertThrows: refactored to support Throwable •  Various improvements to Servlet API mocks 25
  26. 26. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Details, Tips, & Examples 26
  27. 27. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  28. 28. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  29. 29. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  30. 30. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Ex: @ActiveProfiles – Declarative 30 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration @ActiveProfiles("dev") public class IntegrationTests { // ... } But what if static isn’t good enough?
  31. 31. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  32. 32. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Composable Stereotypes – Quick Review •  Combining meta-annotations on a custom stereotype •  Automatically detected: no configuration necessary! 32
  33. 33. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Duplicate Test Configuration == Bad @ContextConfiguration("/test-config.xml") @ActiveProfiles("dev") @Transactional public class OrderRepositoryTests { } @ContextConfiguration("/test-config.xml") @ActiveProfiles("dev") @Transactional public class UserRepositoryTests { } 33 duplication duplication
  34. 34. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Custom Test Annotation == Good @Target(TYPE) @Retention(RUNTIME) @ContextConfiguration("/test-config.xml") @ActiveProfiles("dev") @Transactional public @interface TransactionalDevTest { } @TransactionalDevTest public class OrderRepositoryTests { } @TransactionalDevTest public class UserRepositoryTests { } 34 common config
  35. 35. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  36. 36. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Optional Annotation Attribute Override @Target(TYPE) @Retention(RUNTIME) @ContextConfiguration @Transactional public @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
  37. 37. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Required Annotation Attribute Override @Target(TYPE) @Retention(RUNTIME) @ContextConfiguration @Transactional public @interface TransactionalTest { String[] locations(); } @TransactionalTest(locations = "/order-test-config.xml") public class OrderRepositoryTests { } 37 required no default locations declared here will be ignored
  38. 38. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  39. 39. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  40. 40. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  41. 41. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Ex: Groovy Script Config @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/context.groovy") public class GroovyPersonTests { @Autowired private Person person; /* test methods using person bean */ } 41
  42. 42. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Ex: Default Groovy Script Detection public com.example; @RunWith(SpringJUnit4ClassRunner.class) // ApplicationContext will be loaded from // “classpath:com/example/MyTestContext.groovy” @ContextConfiguration public class MyTest { /* ... */ } 42
  43. 43. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  44. 44. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  45. 45. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license @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
  46. 46. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Ex: @TestPropertySource – locations @ContextConfiguration @TestPropertySource("/test.properties") public class MyIntegrationTests { // class body... } 46
  47. 47. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license @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
  48. 48. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Ex: @TestPropertySource – properties @ContextConfiguration @TestPropertySource( properties = {"foo=bar", "port: 4242"} ) public class MyIntegrationTests { // class body... } 48
  49. 49. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  50. 50. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license @TestPropertySource – Precedence 50 Inlined Files Application & System test precedence
  51. 51. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Ex: @TestPropertySource – locations & properties @ContextConfiguration @TestPropertySource( locations = "/test.properties", properties = "port: 4242" ) public class MyIntegrationTests { // class body... } 51
  52. 52. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  53. 53. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  54. 54. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Ex: Declarative Transaction Management in Tests @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration @Transactional public class TransactionalTests { @Test public void withinTransaction() { /* ... */ } 54 What if we want to stop & start the transaction within the test method?
  55. 55. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  56. 56. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Ex: Programmatic Transaction Management in Tests @Test public 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
  57. 57. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Executing SQL Scripts 57
  58. 58. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Ex: Embedded Database in Java Config 58 @Bean public 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
  59. 59. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  60. 60. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  61. 61. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  62. 62. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  63. 63. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  64. 64. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  65. 65. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  66. 66. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license @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
  67. 67. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license @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 }
  68. 68. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  69. 69. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license In closing… 69
  70. 70. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  71. 71. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license 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
  72. 72. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Blogs Spring Blog: http://spring.io/blog Swiftmind Blog: http://www.swiftmind.com/blog 72
  73. 73. © 2012-2014 Sam Brannen and licensed under a Creative Commons Attribution-NonCommercial license Q & A Sam Brannen @sam_brannen www.slideshare.net/sbrannen www.swiftmind.com 73 @springcentral | spring.io/video

×