我正在为 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. 

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

如果我尝试在我的内部 ContextConfiguration 上使用 @Configuration 而不是 @TestConfiguration,执行会落到另一个极端 - 它以

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

因为,显然,其余的配置没有加载。

如果我尝试放置

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

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

有什么想法吗?

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

请您参考如下方法:

用一个 Bean 进行单元测试

只需使用 @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); 
    } 
} 

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

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

    @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); 
        } 
    } 
    
  • 现在,在您的测试类中使用 @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(...); 
            } 
        } 
     
        ... 
    } 
    


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!