Overriding beans in Integration tests

spring integration test
bean definition override exception
spring boot integration test
spring mockbean
test bean
spring boot test configuration
spring test configuration

For my Spring-Boot app I provide a RestTemplate though a @Configuration file so I can add sensible defaults(ex Timeouts). For my integration tests I would like to mock the RestTemplate as I dont want to connect to external services - I know what responses to expect. I tried providing a different implementation in the integration-test package in the hope that the latter will override the real implementation , but checking the logs it`s the other way around : the real implementation overrides the test one. How can I make sure the one from the TestConfig is the one used?

This is my config file :

public class RestTemplateProvider {

    private static final int DEFAULT_SERVICE_TIMEOUT = 5_000;

    public RestTemplate restTemplate(){
        return new RestTemplate(buildClientConfigurationFactory());

    private ClientHttpRequestFactory buildClientConfigurationFactory() {
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        return factory;

Integration test:

@SpringApplicationConfiguration(classes = TestConfiguration.class)
public abstract class IntegrationTest {}

TestConfiguration class:

@Import({Application.class, MockRestTemplateConfiguration.class})
public class TestConfiguration {}

And finally MockRestTemplateConfiguration

public class MockRestTemplateConfiguration {

    public RestTemplate restTemplate() {
        return Mockito.mock(RestTemplate.class)

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

How to override Spring Bean in integration test with custom bean , 1 Answer. You can use @SpyBean - then bean can be stubbed for specific cases (like in the case of @MockBean ), but otherwise real bean will be used. Also, if you actually need to define custom bean definition for tests, then combination of @Primary / @Profile / @ContextConfiguration can be used for this purpose. I have a problem with overriding beans in integration tests in Spring (with Spock). Let's say this is my application config: @EnableWebMvc @SpringBootApplication @Configuration class Main { @

1. You can use @Primary annotation:

public class MockRestTemplateConfiguration {

    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;

  private RestTemplate restTemplate;

  private UsersClient usersClient;

  public void init() {
    mockServer = MockRestServiceServer.createServer(restTemplate);

  public void testSingleGet() throws Exception {
    // GIVEN
    int testingIdentifier = 0;
    mockServer.expect(requestTo(USERS_URL + "/" + testingIdentifier))
      .andRespond(withSuccess(TEST_RECORD0, MediaType.APPLICATION_JSON));

    // WHEN
    User user = usersClient.getUser(testingIdentifier);

    // THEN
    assertEquals(user.getName(), USER0_NAME);
    assertEquals(user.getEmail(), USER0_EMAIL);

More examples can be found in my Github repo here

Spring-Boot 2.1.x and overriding bean definition, Check our article explaining the issue of overriding Spring Bean Now, for a test I wanted to override these 2 bean definitions and did  Overriding an Autowired Bean in Unit Tests. Is there a simple way I can easily override an autowired bean in specific unit tests? There is only a single bean of every type in the compile classes so it's not a problem for autowiring in this case. The test classes would contain additional mocks.

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 tree
public class Main{

Main config

public void AppConfig() { 
    // Define any beans

Test config

public void AppTestConfig(){
    // override beans for testing

Test class

public 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.

14. Integration Testing - Project Metadata API Guide, The Spring Framework provides first-class support for integration testing in the Beans defined in ExtendedConfig may therefore override (i.e., replace) those  Overriding Profiles in Spring Boot Integration Tests We will now see how to override configured profile with the one passed through command line arguments. In order to do so, we will utilize resolver concept of @ActiveProfiles annotation.

Getting a little deeper into it, see my second answer.

I solved the Problem using

@SpringBootTest(classes = {AppConfiguration.class, AppTestConfiguration.class})

instead of

@Import({ AppConfiguration.class, AppTestConfiguration.class });

In my case the Test is not in the same package as the App. So I need to specify the AppConfiguration.class (or the App.class) explicit. If you use the same package in the test, than I guess you could just write

@SpringBootTest(classes = AppTestConfiguration.class)

instead of (not working)

@Import(AppTestConfiguration.class );

It is pretty wired to see that this is so different. Maybe some one can explain this. I could not find any good answers until now. You might think, @Import(...) is not picked up if @SpringBootTestsis present, but in the log the overriding bean shows up. But just the wrong way around.

By the way, using @TestConfiguration instead @Configuration also makes no difference.

Override bean in Spring Boot 2.1 slice test with nested , One of my test is failing due to a change to bean overriding default. I tried to in my case because a slice test is not really an integration test. When running an integration style test we find we need to override properties or even entire beans in the production configuration to allow tests to run quickly by swapping out real resources with mocked or faked implementations. Use-Case B. Frameworks built on top of Spring often ship with some 'default' configuration.

@MockBean and bean overriding used by the OP are two complementary approaches.

You want to use @MockBean to create a mock and forget the real implementation : generally you do that for slice testing or integration testing that doesn't load some beans which class(es) you are testing depend on and that you don't want to test these beans in integration. Spring makes them by default null, you will mock the minimal behavior for them to fulfill your test.

@WebMvcTest requires very often that strategy as you don't want to test the whole layers and @SpringBootTest may also require that if you specify only a subset of your beans configuration in the test configuration.

On the other hand, sometimes you want to perform an integration test with as many real components as possible, so you don't want to use @MockBean but you want to override slightly a behavior, a dependency or define a new scope for a bean, in this case, the approach to follow is bean overriding :

public class FooTest{    

    public void getFoo() throws Exception {
        // ...     

    public static class OverrideBean {    

        // change the bean scope to SINGLETON
        public Bar bar() {
             return new Bar();

        // use a stub for a bean 
        public FooBar BarFoo() {
             return new BarFooStub();

        // use a stub for the dependency of a bean 
        public FooBar fooBar() {
             return new FooBar(new StubDependency());


The BeanDefinitionOverrideException in Spring Boot, Can we have two beans with same name in spring? The spring-boot-starter-test dependency contains everything we need to override the property value in the tests. First, we'll have to create a class in the application that will use our properties: public class PropertySourceResolver { @Value("$ {example.firstProperty}") private String firstProperty; @Value("$ {example.secondProperty}") private

Defining the same Spring bean twice with same name, How do you write integration test cases in spring boot? Overriding beans for testing forum.springsource.org. Overriding beans for testing Hi. I am trying to set up an integration test, so I want to load all of my contexts. One of them is for a DataSource and

Integration Testing with Spring, How can we use @Primary in integration tests? @Primary becomes very effective in tests, because we might want to override the bean that is  The Spring Framework provides first-class support for integration testing in the spring-test module. The name of the actual JAR file might include the release version and might also be in the long org.springframework.test form, depending on where you get it from (see the section on Dependency Management for an explanation).

Integration Tests with @SpringBootTest, Before we start into integration tests with Spring Boot, let's define There's a lot of other auto-configurations available that each add other beans to the If the property foo exists in the default setting, it will be overridden by  The spring-boot-starter-test is the primary dependency that contains the majority of elements required for our tests. The H2 DB is our in-memory database. It eliminates the need for configuring and starting an actual database for test purposes. 4. Integration Testing With @DataJpaTest. We're going to work with an entity named Employee which has

  • Switch the order of the imports, they are parsed in the way they are read, so the later ones override the previous ones.
  • Tried it ...same thing. I`ll update my question to reflect the changes
  • Possible duplicate of Overriding an Autowired Bean in Unit Tests
  • agree that this is the way to go in most cases. The down-side that I found with this approach is that you will lose the benefit of Context caching in your next test class. To make our integrations tests as fast as possible we extend one class whenever possible.
  • true, but sometimes there's no other way. E.g. when you need to fake external services.
  • haha. very interesting. Thanks for the effort ...Efficient trick indeed.
  • The annotation is @MockBean, see docs.spring.io/spring-boot/docs/current/reference/html/…
  • This is a good solution, but my problem cannot be solved this way because I am doing AOP security-related testing.
  • I tried the second suggestion and it works great. Thanks for the hint..I feel this is the "correct" way to go.
  • Thanks. Option 1 worked for me with a simple @Primary annotation on my TestMock Bean which took precedent over the Production one for @Autowire of fields in my Test classes. Apart from this @Primary annotation, no other change was required.
  • this (#1) should be accepted answer. so amazingly simple
  • Disclaimer: this annotation is not supported in earlier Spring versions, it is available since Spring Boot 1.4.0