get the most out of testing with spring 4.2
TRANSCRIPT
SPRINGONE2GX WASHINGTON, DC
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Get the Most out of Testing with Spring 4.2
Sam Brannen @sam_brannen
Nicolas Fränkel @nicolas_frankel
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Sam Brannen
• Spring and Enterprise Java Consultant @ Swiftmind • Java Developer for over 17 years
• Spring Framework Core Committer since 2007 • Component lead for spring-test • Creator of @AliasFor
• Spring Trainer • Speaker on Spring, Java, and testing
• Swiss Spring User Group Lead
2
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 3
Your experts for Spring and Enterprise Java
Areas of expertise
• Spring *
• Java EE
• Software Architecture
• Software Engineering Best Practices
Where you find us
• Zurich, Switzerland
• @swiftmind
• http://www.swiftmind.com
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Nicolas Fränkel
• Developer & Architect
• Consultant
• Teacher & Trainer
• Blogger
• Book Author
4
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Learning Vaadin 7 Integration Testing from the Trenches
5
Nicolas’ Books
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Agenda
• Spring Events App
• New in Spring 4.2
• JUnit vs. TestNG
• Spring Boot Tests
• Spring Security Tests
• Tips & Tricks
6
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Show of hands…
7
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Spring Events App
8
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
The Spring Events Example Application
• Spring Boot powered web app
• Simple POJO domain model: Event
• Transactional service layer
• Spring Data JPA repository layer
• Spring @MVC +Thymeleaf & REST presentation layer
• Spring Security
• https://github.com/sbrannen/spring-events
9
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
New in Spring Framework 4.2
10
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
@AliasFor
• New in Spring Framework 4.2, refined in 4.2.1 !
• Used to declare aliases between attributes within an annotation
• e.g., locations and value in @ContextConfiguration, or path and value in @RequestMapping
• Used in composed annotations to declare explicit overrides of attributes in meta-annotations
• e.g., @Get, @Post, @GetJson, @TransactionalService
• See Spring Composed project for examples
• https://github.com/sbrannen/spring-composed
11
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Composable Annotations w/ Overrides: pre 4.2
• Composable annotations can 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
12
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Convention-based Attribute Override
@Target(TYPE)@Retention(RUNTIME)@ContextConfiguration@Transactionalpublic @interface TransactionalTest { String[] locations() default {};}
@TransactionalTest(locations = "/order-test-config.xml")public class OrderRepositoryTests { }
13
seen as locations in @ContextConfiguration
redeclares locations attribute
declares locations attribute
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Conflict w/ Convention-based Attribute Override
@Target(TYPE)@Retention(RUNTIME)@ContextConfiguration@TestPropertySource@Transactionalpublic @interface TransactionalTest { String[] locations() default {};}
@TransactionalTest(locations = "/order-test-config.xml")public class OrderRepositoryTests { }
14
both declare locations attribute
ambiguous
which one?!
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Composable Annotations w/ Overrides: post 4.2
• Composable annotations can explicitly override attributes of meta-annotations, even transitively
• Attributes within an annotation that effectively override the same attribute are treated as implicit aliases for each other
• Explicitly declared via @AliasFor
• Can avoid potential naming conflicts
• Can even override the value attribute
15
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Avoid Attribute Override Conflict w/ @AliasFor (1)
@ContextConfiguration@TestPropertySource@Transactionalpublic @interface TransactionalTest {
@AliasFor(annotation = ContextConfiguration.class, attribute = "locations") String[] xmlFiles() default {};
@AliasFor(annotation = TestPropertySource.class, attribute = "locations") String[] propFiles() default {};}
16
both declare locations attribute
explicit
explicit
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Avoid Attribute Override Conflict w/ @AliasFor (2)
@TransactionalTest( xmlFiles = "/order-test-config.xml", propFiles = "/order-test.properties")public class OrderRepositoryTests {}
17
seen as locations in @ContextConfiguration
seen as locations in @TestPropertySource
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Embedded Databases – What’s in a Name?
Q: Why should I care what my embedded database is named? A: Because you’ll run into problems if your DataSource config is imported from multiple places within your test suite.
Q: Why? Doesn’t it just create a new instance of the database?
A: Recreating an embedded database within the same JVM doesn’t actually create anything: a second attempt simply connects to the existing one.
Q: Ummmm… What?! A: When you connect to an embedded database, it gets created if it doesn’t already exist; otherwise, you just connect to the existing instance. Assigning each one a unique name results in different JDBC connection URLs and thus different instances.
18
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Unique Names for Embedded Databases
19
• EmbeddedDatabaseBuilder
• setName() – available since 3.0
• generateUniqueName() – available since 4.2
• <jdbc:embedded-database>
• id – used as name since 3.0
o but bad since the id is usually “dataSource”... not unique
• database-name – available since 4.2
• generate-name – available since 4.2
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Ex: Embedded Database in Java Config
20
@Beanpublic DataSource dataSource() { return new EmbeddedDatabaseBuilder() .generateUniqueName(true) .addScript("schema.sql") .addScript("user_data.sql") .build();}
New in Spring 4.2
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Ex: Embedded Database XML Config
21
<jdbc:embedded-database id="dataSource" generate-name="true"> <jdbc:script location="classpath:/schema.sql" /> <jdbc:script location="classpath:/user_data.sql" /></jdbc:embedded-database>
New in Spring 4.2
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Spring Cleaning
• @TransactionConfiguration
• Deprecated in 4.2
• @Rollback (and @Commit) now supported at the class level
• Use @Transactional qualifiers
• AssertThrows
• Deprecated in 3.x; gone in 4.2
• JUnit: use @Test(expected = ...) or @Rule ExpectedException
• TestNG: use @Test(expectedExceptions = ...)
22
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Extension Points
• ContextCache
• Now a public API with DefaultContextCache implementation
• DefaultTestContext, DefaultBootstrapContext, and DefaultCacheAwareContextLoaderDelegate
• Now public classes, allowing for custom extensions
• TestContextBootstrapper
• Now responsible for building the TestContext
23
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Spring + JUnit … @Rules!
• SpringJUnit4ClassRunner
• Serving the community since Spring 2.5 (2007)
• But… can’t be used with other runners
o JUnit's Parameterized, MockitoJUnitRunner, etc.
• SpringClassRule & SpringMethodRule
• Since Spring 4.2
• Can be used with any JUnit runner!
• Have to be used together
• Provide full power of the Spring TestContext Framework
24
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Ex: SpringClassRule & SpringMethodRule
25
@RunWith(Parameterized.class)@ContextConfigurationpublic class ParameterizedSpringRuleTests {
@ClassRule public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
@Rule public final SpringMethodRule springMethodRule = new SpringMethodRule();
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
HtmlUnit, Selenium, & Geb
• First-class support for HtmlUnit and Selenium in Spring MVC Test
• Initially a stand-alone project
• Incorporated into spring-test in Spring 4.2
• Page-based web app testing w/o a Servlet container
• The Selenium support can also be used with Geb
26
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
MockMvc & HtmlUnit WebClient Setup
• spring-test (4.2+) & htmlunit (2.18+)
• MockMvcWebClientBuilder: several options, simplest case below
27
@Autowired WebApplicationContext wac;
WebClient webClient;
@Beforepublic void setup() { webClient = MockMvcBuilders .webAppContextSetup(wac).build();}
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
MockMvc & Selenium WebDriver Setup
• spring-test (4.2+) & selenium-htmlunit-driver (2.47+)
• MockMvcHtmlUnitDriverBuilder: several options, simplest case below
28
@Autowired WebApplicationContext wac;
WebDriver driver;
@Beforepublic void setup() { driver = MockMvcHtmlUnitDriverBuilder .webAppContextSetup(wac).build();}
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Odds & Ends (1)
• ReflectionTestUtils
• Now you can get or set static fields, including constants
• AopTestUtils
• Obtain reference to target object hidden behind one or more Spring proxies
• Useful if your mock gets proxied
• @DirtiesContext
• New BEFORE_METHOD, BEFORE_CLASS, & BEFORE_EACH_TEST_METHOD modes
• Requires DirtiesContextBeforeModesTestExecutionListener, enabled by default
29
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
ReflectionTestUtils vs. Proper Design
• Proper design mandates that we use the most narrow visibility possible.
• But it’s sometimes meaningful to test private methods, or change values of final fields, etc.
• As a work-around, set the visibility to package (no keyword) and put the test class in the same package.
• Guava provides the @VisibleForTesting annotation to document this hack.
• ReflectionTestUtils is an alternative to such work-arounds that promotes proper design.
30
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Odds & Ends (2)
• @Commit • Syntactical sugar for @Rollback(false)
• Inlined statements with @Sql
• For when a dedicated SQL script is overkill
• Configured via a new statements attribute
• Executed after SQL scripts in same @Sql annotation
• Great for one-liners
• Spring MVC Test - MvcResult logging
• New log(), print(OutputStream), and print(Writer) methods in MockMvcResultHandlers complement existing print() method
31
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 32
@Test@Sql(statements = "DROP TABLE user IF EXISTS")@Sql( scripts = "/test-schema.sql", statements = "INSERT INTO user VALUES ('Dilbert')")public void userTest() { // code that uses the test schema and test user}
Ex: Inlined @Sql Statements
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 33
@Beforepublic void setUpMockMvc() { mockMvc = MockMvcBuilders .webAppContextSetup(wac) .alwaysDo(print(System.err)) .build();}
Ex: Logging MvcResult to STDERR
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
JUnit vs TestNG
34
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
TestNG
• Implemented annotations before JUnit
• Richer lifecycle
• Ordering of test methods
• Concurrent test execution
35
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
JUnit
• Unit for… unit testing!
• Simplicity can be both a pro and a con
• Lacks ordering… unless you use @FixMethodOrder
• Single runner
• Spring OR Mockito OR Parameterized
• Rules to the rescue
36
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Spring Boot Tests
37
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Integration Tests with Spring Boot
• @SpringApplicationConfiguration
• Like @ContextConfiguration but with SpringApplicationContextLoader
• Fully Loaded
• @IntegrationTest
o IntegrationTestPropertiesListener vs. @TestPropertySource
• @WebIntegrationTest
• Limiting scope of auto-configuration
• @TestRepositoryConfig as example
38
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Spring Security Tests
39
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Spring Security – Test Annotations
• WithSecurityContextTestExecutionListener
• auto-detected
• @WithMockUser
• See RestEventsControllerIT in spring-events
• @WithUserDetails
• @WithSecurityContext
40
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Spring Security & MockMvc
• apply(springSecurity())
• with(...) • user(...)
• authentication(...)
• securityContext(...)
• httpBasic(...)
• perform(...)
• formLogin()
• logout()
41
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Testing Tips & Tricks
42
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Eclipse
• Define key bindings for executing tests quickly
• Alt + Shift + X… T " too awkward to type frequently!
• Sam’s personal settings:
o Run JUnit Test " Ctrl + J
o Rerun JUnit Test " Ctrl + Shift + J
• Set up content assist favorites for common static imports
• org.junit.Assert OR org.assertj.core.api.Assertions
• org.mockito.Mockito
• org.springframework.test.web.servlet.request.MockMvcRequestBuilders
• org.springframework.test.web.servlet.result.MockMvcResultMatchers
43
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Context Caching
• Granularity of context configuration files
• Goal: one entry point for production and one for testing
• But… not very practical: you’ll need to support different scenarios
• Too many constellations " too many contexts
• Too few constellations " all tests use the same config
• Optimum use of the context cache
• Avoid frequent use of @DirtiesContext
• Cache statistics are logged at DEBUG level for category org.springframework.test.context.cache
44
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Integration Tests: Spring Boot vs. Spring Core
• @SpringApplicationConfiguration vs. @ContextConfiguration
• @EnableAutoConfiguration vs. hand-crafted test @Configuration
• See @TestRepositoryConfig in spring-events app
45
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Scope
• Think about the scope of your test
• SUT: System Under Test
• The larger the SUT the smaller the number of tests
• Mock or fake the dependencies of your SUT
46
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
End-to-end testing
• A few nominal scenarios
• Very brittle
• Use the Page pattern
• Decouples the page structure from the test itself
47
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Integration Testing Challenges
• Speed
• Hard to diagnose
• Brittle
48
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Speed
• Integration Tests are slow
• Run Unit Tests before
• No need to run IT if UT fail
• If you use Maven, use the maven-failsafe-plugin
• If you use Gradle, good luck !
49
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Hard to Diagnose
• Use small aptly named methods
• Order them
• E-commerce checkout
50
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Brittle
• All applications have infrastructure dependencies
• Database, web services, file system, time, etc.
• They can be unavailable during testing
• That sends a bad signal to developers
• Fake them (or try to)
51
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Fake Databases
• Prefer a single schema per developer if you can
• H2 has an Oracle compatibility mode
• Be aware of the gap if you’re not using the same RDBMS in tests as in production
52
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Fake Web Services
• SOAP
• SoapUI has an API
• REST
• Spark
53
setPort(5678);get("/hello", (request, response) -> {
return "Hello World!";});
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Data source pool exhaustion check
• Set the maximum number of connections in the pool to 1
54
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Checking the database when a test fails
• Commit your transactions in your tests
• Use a clean setup strategy
• Instead of a clean tear down
• Use a file based database
• H2
55
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Testing is about Money
• Not about having more test coverage than your neighbor
• Think about ROI
56
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
JUnit Lambda
57
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Give back to the project that’s given us so much!
• JUnit is the de facto standard testing framework in the Java ecosystem
• Last major release 10 years ago
• Times have changed: Java 8, etc.
• Introducing … JUnit Lambda … the crowdfunding campaign to help make the next major release of JUnit a reality
• Pitch in if you can, & help spread the word!
• @JUnitLambda • https://www.indiegogo.com/projects/junit-lambda
58
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
In closing…
59
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
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, spring-boot, spring-security, …
60
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/
Blogs
Spring Blog
http://spring.io/blog
Swiftmind Blog
http://www.swiftmind.com/blog
Nicolas Fränkel’s Blog
https://blog.frankel.ch
61
© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 62
Sam Brannen
@sam_brannen
www.slideshare.net/sbrannen
www.swiftmind.com
Learn More. Stay Connected.
@springcentral Spring.io/video Nicolas Fränkel
@nicolas_frankel