11

Spring Boot 1.4 offers some fantastic testing improvements. One is the @DataJpaTest annotation where it wires up just the parts needed for JPA testing. What would the equivalent look like for just wiring up the parts needed for JdbcTemplate tests?

I'm fine constructing my own composite annotation that mimics the @DataJpaTest one.

checketts
  • 14,167
  • 10
  • 53
  • 82

2 Answers2

20

Good question. Ironically enough, that one was raised during the testing talk yesterday at SpringOne Platform. Let's see what it takes to implement such dedicated test annotation.

TL;DR check the code on github

First of all you need to create the annotation. This annotation reuses some bits from the spring-boot-test-autoconfigure module. You may want to auto-configure an in-memory database (like DataJpaTest does). You also want to make sure that caching is configured and disabled by default (in case you have @EnableCaching on your Spring Boot application). You also want that all your tests are @Transactional by default so you should add that.

Next, you want that slicing effectively kicks in. All you need at this point is a DataSource, a JdbcTemplate, database migrations (flyway/liquibase) and a transaction manager to process @Transactional. To avoid the other auto-configurations to kick in you should add the following:

@OverrideAutoConfiguration(enabled = false)

Then, you want to explicitly enable the auto-configurations above. In order to do so, you add @ImportAutoConfiguration and you add the following content in META-INF/spring.factories

# AutoConfigureDataJpa auto-configuration imports
com.example.test.autoconfigure.jdbc.DataJdbcTest=\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\      
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\    
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration

The key in spring.factories should match the FQN of your annotation. Whenever Spring Boot finds @ImportAutoConfiguration with no extra attributes, it will look for a key matching the annotation type in spring.factories.

Next up you want to be able to include additional components (component scan) with a filter. In order to do that, you can add @TypeExcludeFilters(DataJdbcTypeExcludeFilter.class) where DataJdbcTypeExcludeFilter is pretty much the same thing as DataJpaTypeExcludeFilter (so we might want to extract a common class for that).

Once you've done that, you only need to add your annotation and your JdbcTemplate is auto-configured for you

@RunWith(SpringRunner.class)
@DataJdbcTest
public class DataJdbcSampleTests {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    ...
}
Stephane Nicoll
  • 31,977
  • 9
  • 97
  • 89
  • 3
    Thanks for the excellent answer! Also, I'm the fellow that raised the question in the session ;) – checketts Aug 03 '16 at 15:48
  • That's awesome! I am glad it helps. – Stephane Nicoll Aug 03 '16 at 15:56
  • the solution is fantastic, however I ran into a bug in `TestDatabaseAutoConfiguration` where it is trying to log out the `DataSource` by `logger.info("Replacing \'" + holder.getBeanName() + "\' DataSource bean with embedded version");` but is instead getting a `NullPointerException` – checketts Aug 08 '16 at 20:46
  • NPE on a typo seems harsh. Can you please report what you had and the exception in our tracker? We'll hava a look to improve the error message. – Stephane Nicoll Aug 10 '16 at 12:46
0

I think the option will be @JdbcTest, you could found further info on doc.

nekperu15739
  • 3,311
  • 2
  • 26
  • 25