编程语言
首页 > 编程语言> > java-SpringBootTest-如何在运行时配置中替换一个bean?

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

作者:互联网

我正在为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毫无用处.

解决方法:

一个豆的单元测试

只需使用@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.class和ContextConfiguration.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(...);
        }
    }

    ...
}

标签:spring-boot,testing,integration-testing,spring,java
来源: https://codeday.me/bug/20191025/1930295.html