SpringBootTest - how to replace one bean in runtime configuration?

Alexander :

I am writing an integration test for Spring Boot application. All goes well as long as I'm using 100% runtime configuration for the test. But when I'm trying to provide just one custom bean for the bean, everything breaks.

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class CombinedControllerIntegrationTest2 {

@TestConfiguration
static class ContextConfiguration {

    @Bean
    @Primary
    public SolrDocumentTypeMapRepository solrDocumentTypeMapRepository() {
        LOG.debug("SolrDocumentTypeMapRepository is being initialized.");

// etc.

code variant above is causing the real, runtime SolrDocumentTypeMapRepository to load. ContextConfiguration in my test class is ignored.

If I try to use @Configuration instead of @TestConfiguration on my inner ContextConfiguration, execution falls to another extreme - it ends with

org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.

Because, apparently, the rest of configuration is not loaded.

If I try to put

@ContextConfiguration(classes = {CombinedControllerIntegrationTest2.ContextConfiguration.class,GatewayApplication.class})

on my main testing class, it fails the same way as in #1 - i.e. my ContextConfiguration is ignored.

Any ideas?

P.S. I know I can use @MockBean (and this even works in other cases), but here, because at some point I have dependency on @PostConsruct methods in the main code, @MockBeans are useless.

Indra Basak :

Unit Test with One Bean

Just use @RunWith(SpringRunner.class) annotation, it should work. You can also use @RunWith(SpringJUnit4ClassRunner.class). Both should work.

Please don't use @SpringBootTest annotation. It will wire up the whole application.

Here is your updated example,

@RunWith(SpringRunner.class)
public class CombinedControllerIntegrationTest2 {

    @TestConfiguration
    static class ContextConfiguration {

        @Bean
        public SolrDocumentTypeMapRepository solrDocumentTypeMapRepository() {
            LOG.debug("SolrDocumentTypeMapRepository is being initialized.");
            return new SolrDocumentTypeMapRepository(...);
        }
    }

    @Autowired
    private SolrDocumentTypeMapRepository repository;

    @Test
    public void test() {
        assertNotNull(repository);
    }
}

Integration Test with a Replaced Bean

  • Create a new test Spring Boot application. It should exclude the configuration class (for e.g., SolrConfiguration) which is responsible for creating SolrDocumentTypeMapRepository bean.

    @SpringBootApplication
    @ComponentScan(basePackages = {
            "com.abc.pkg1",
            "com.abc.pk2"},
            excludeFilters = {
                    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, 
                    value = SolrConfiguration.class)})
    public class TestApplication {
        public static void main(String[] args) throws Exception {
            SpringApplication.run(TestApplication.class, args);
        }
    }
    
  • Now, use the @ContextConfiguration annotation in your test class to add the TestApplication.class and the ContextConfiguration.class. This will wire up your application with the all the required beans including the replaced bean. Shown below is the updated test class,

    @ActiveProfiles("test")
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(webEnvironment = 
        SpringBootTest.WebEnvironment.RANDOM_PORT)
    @ContextConfiguration(classes = {TestApplication.class, 
        CombinedControllerIntegrationTest2.ContextConfiguration.class})
    public class CombinedControllerIntegrationTest2 {
    
        @TestConfiguration
        static class ContextConfiguration {
    
            @Bean
            public SolrDocumentTypeMapRepository solrDocumentTypeMapRepository() {
                LOG.debug("SolrDocumentTypeMapRepository is being initialized.");
                return new SolrDocumentTypeMapRepository(...);
            }
        }
    
        ...
    }
    

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=476452&siteId=1
Recommended