Overriding beans in Integration tests
Since Spring Boot 1.4.x there is an option to use @MockBean
annotation to fake Spring beans.
Reaction on comment:
To keep context in cache do not use @DirtiesContext
, but use @ContextConfiguration(name = "contextWithFakeBean")
and it will create separate context, while it will keep default context in cache. Spring will keep both (or how many contexts you have) in cache.
Our build is this way, where most of the tests are using default non-poluted config, but we have 4-5 tests that are faking beans. Default context is nicely reused
1.You can use @Primary
annotation:
@Configurationpublic class MockRestTemplateConfiguration { @Bean @Primary public RestTemplate restTemplate() { return Mockito.mock(RestTemplate.class) }}
BTW, I wrote blog post about faking Spring bean
2.But I would suggest to take a look at Spring RestTemplate testing support. This would be simple example:
private MockRestServiceServer mockServer; @Autowired private RestTemplate restTemplate; @Autowired private UsersClient usersClient; @BeforeMethod public void init() { mockServer = MockRestServiceServer.createServer(restTemplate); } @Test public void testSingleGet() throws Exception { // GIVEN int testingIdentifier = 0; mockServer.expect(requestTo(USERS_URL + "/" + testingIdentifier)) .andExpect(method(HttpMethod.GET)) .andRespond(withSuccess(TEST_RECORD0, MediaType.APPLICATION_JSON)); // WHEN User user = usersClient.getUser(testingIdentifier); // THEN mockServer.verify(); assertEquals(user.getName(), USER0_NAME); assertEquals(user.getEmail(), USER0_EMAIL); }
More examples can be found in my Github repo here
The Problem in your configuration is that you are using @Configuration
for your test configuration. This will replace your main configuration. Instead use @TestConfiguration
which will append (override) your main configuration.
46.3.2 Detecting Test Configuration
If you want to customize the primary configuration, you can use a nested @TestConfiguration class. Unlike a nested @Configuration class, which would be used instead of your application’s primary configuration, a nested @TestConfiguration class is used in addition to your application’s primary configuration.
Example using SpringBoot:
Main class
@SpringBootApplication() // Will scan for @Components and @Configs in package treepublic class Main{}
Main config
@Configurationpublic void AppConfig() { // Define any beans}
Test config
@TestConfigurationpublic void AppTestConfig(){ // override beans for testing}
Test class
@RunWith(SpringRunner.class)@Import(AppTestConfig.class)@SpringBootTestpublic void AppTest() { // use @MockBean if you like}
Note: Be aware, that all Beans will be created, even those that you override. Use @Profile
if you wish not to instantiate a @Configuration
.