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.