SpringBootTest-如何在运行时配置中替换一个bean?

Ale*_*der 5 java testing spring integration-testing spring-boot

我正在为Spring Boot应用程序编写集成测试。只要我使用100%运行时配置进行测试,一切都会顺利进行。但是,当我尝试仅为该bean提供一个自定义bean时,一切都会中断。

@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.
Run Code Online (Sandbox Code Playgroud)

上面的代码变体导致实际的运行时SolrDocumentTypeMapRepository加载。我的测试类中的ContextConfiguration被忽略。

如果我尝试在内部ContextConfiguration上使用@Configuration而不是@TestConfiguration,则执行会陷入另一个极端-它以结尾

org.springframework.context.ApplicationContextException:由于缺少EmbeddedServletContainerFactory bean而无法启动EmbeddedWebApplicationContext。

因为,显然,其余配置未加载。

如果我尝试放

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

在我的主测试类上,它以与#1相同的方式失败-即,我的ContextConfiguration被忽略。

有任何想法吗?

PS我知道我可以使用@MockBean(甚至在其他情况下也可以使用),但是在这里,因为在某些时候我依赖于主代码中的@PostConsruct方法,所以@MockBeans毫无用处。

Ind*_*sak 11

一个豆的单元测试

只需使用@RunWith(SpringRunner.class)注释,它应该可以工作。您也可以使用@RunWith(SpringJUnit4ClassRunner.class)。两者都应该起作用。

请不要使用 @SpringBootTest注释。它将连接整个应用程序。

这是您的更新示例,

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

使用替换的Bean进行集成测试

  • 创建一个新的测试Spring Boot应用程序。它应排除SolrConfiguration负责创建SolrDocumentTypeMapRepositorybean 的配置类(例如)。

    @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);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 现在,使用@ContextConfiguration测试类中的注释添加TestApplication.classContextConfiguration.class。这将使您的应用程序与所有必需的bean(包括替换的bean)连接起来。下面显示的是更新的测试类,

    @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(...);
            }
        }
    
        ...
    }
    
    Run Code Online (Sandbox Code Playgroud)