/spring-boot-testing-use-cases

Describes various testing use cases

Primary LanguageJava

Testing use cases

This project gathers some testing use cases used on the field. They demonstrate areas where our support is lacking. This got handled as of Spring Boot 1.4 that has a major overhaul of testing support.

Primary mock

Mocking a component that has certain dependencies can be hard, especially if it is injected by type in other component(s) in an integration test. The spring-boot-testing-mock-primary project shows how to use @Primary to override a bean definition with a mock.

Observations

  • The "production" instance is still created (albeit not injected in other components) so it must not do something on startup that requires a service connectivity

  • This seems like an abusive use of @Primary

  • In order to control when the mock should or should not apply, these test configurations must be put outside of the main package to prevent a default @ComponentScan to pick them up

The relation between SampleApplication and ServerMockConfiguration is also problematic. We may think that because the latter is added after the main test configuration, any bean defined in the mock configuration can effectively override a matching bean in the main configuration. Unfortunately, @ComponentScan is applied at a latter stage and there might be no guarantee of what wins on what.

Open questions

  • Can we improve the context initialization so that @ComponentScan provides a deterministic behaviour? (i.e. any class added after a @SpringBootApplication has a chance to override components that are detected by component scan).

  • Can we improve the component scan to ignore certain configs by default? This would allow us not to put our mock config in a different package space

Test profile

Another way to mock components is to define them in a test profile. To avoid defining them twice (as in the previous example), regular configuration may not use component scan for those and register them in a configuration class that is annotated @Profile("!test"). The spring-boot-testing-profile project demonstrates this.

Observations

  • The configuration becomes quite hard to read with this profile dance (in test, not in test).

  • This assumes that there is one testing configuration and one "production" configuration. Anything more complex would be quite hard to manage that way

Mock Bean

Spring Boot 1.4 introduces a new MockBean annotation that allows to handle mocks on a per test-basis. Just annotate any dependency you’d like to mock with @MockBean at the class level. Assertions can be written directly in your test and the mock is reset after each test automatically. The spring-boot-testing-mock-bean project shows how to use this new feature.