我正在为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:无法执行 由于缺少启动EmbeddedWebApplicationContext EmbeddedServletContainerFactory bean。
因为显然没有加载其余的配置。
如果我试图把
@ContextConfiguration(classes = {CombinedControllerIntegrationTest2.ContextConfiguration.class,GatewayApplication.class})
在我的主测试类上,它的失败方式与#1相同 - 即我的ContextConfiguration被忽略。
有什么想法吗?
P.S。我知道我可以使用@MockBean(这甚至适用于其他情况),但是在这里,因为在某些时候我依赖于主代码中的@PostConsruct方法,所以@MockBeans没用。
答案 0 :(得分:5)
只需使用@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);
}
}
创建一个新的测试Spring Boot应用程序。它应该排除负责创建SolrConfiguration
bean的配置类(例如SolrDocumentTypeMapRepository
)。
@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(...);
}
}
...
}
答案 1 :(得分:0)
使用@Mockean模拟您的存储库。并在测试中添加行为:
@SpringBootTest
@AutoConfigureMockMvc
@RunWith(SpringRunner.class)
public abstract class IntegrationTest {
@MockBean
SolrDocumentTypeMapRepository solrDocumentTypeMapRepository;
@Test
public void mySuperTest(){
Mockito.when(solrDocumentTypeMapRepository.getById(Mockito.any())).thenReturn(someInstance);
Assert.assertEquals(solrDocumentTypeMapRepository.getById("someId"), someInstance);
}
}
答案 2 :(得分:-2)
使用@RunWith(SpringRunner.class)而不是使用@Runwith(SpringJunit4Classrunner.class)。这应该可以帮助你解决错误。