【发布时间】:2018-12-08 17:35:08
【问题描述】:
在我的 Spring boot 2.1 项目中,我有不同的 @Configurations 用于不同的测试(ConfigurationA 和 ConfigurationB),它们位于不同的包中。两种配置都定义了相同的一组 bean,但方式不同(模拟与真实)
由于我知道 Spring Boot 2.1 中引入了 Bean overriding 机制,因此我设置了属性:spring.main.allow-bean-definition-overriding=true。
但是,我确实对以下配置和测试类的设置进行了测试。首先在生产部分有一个@Configuration(我使用的是Maven):
package com.stackoverflow;
@Configuration
public class ProdConfiguration{
...
}
那么在测试分支中就有一个通用的Test@Configuration在同一个包级别:
package com.stackoverflow
@Configuration
public class TestConfiguration {
@Bean
public GameMap gameMap() {
return Mockito.mock(GameMap.class);
}
}
在一个子包中我还有另一个@Configuration:
package com.stackoverflow.impl;
@Configuration
public class RealMapTestConfiguration {
@Bean
public GameMap gameMap() {
return new GameMap("testMap.json");
}
}
当然还有困扰我的测试:
package com.stackoverflow.impl;
@ExtendWith(SpringExtension.class)
@SpringBootTest
@ContextConfiguration(classes={RealMapTestConfiguration.class, ProdConfiguration.class})
@ActiveProfiles("bug") // spring.main.allow-bean-definition-overriding=true
public class MapImageServiceIT {
@Autowired
private GameMap map;
}
事实证明,注入到我的测试中的GameMap 是来自TestConfiguration 的模拟实例,而不是来自RealMapTestConfiguration 的真实实例。 Aparrently 在我的测试中,当我想要ProdConfiguration 和RealMapTestConfiguration 时,我有来自ProdConfiguration 和TestConfiguration 的配置。由于ProdConfiguration 和*TestConfiguration 中定义的bean 不同,因此组合有效,但TestConfiguration 和RealMapTestConfiguration 定义相同。似乎TestConfiguration 被组件扫描拾取,因为它与ProdConfiguration 在同一个包中。
我的印象是,在覆盖 bean 时,更接近测试类的 bean 定义将是首选。然而,情况似乎并非如此。
所以这是我的问题:
- 覆盖 bean 时,顺序是什么?哪个 bean 覆盖了哪个?
- 如何在我的测试中获取正确的实例(使用不同的 bean 名称不是一个选项,因为实际上注入的 bean 不是直接在测试中使用,而是在测试使用的服务中,并且没有限定符。)
【问题讨论】:
-
您是否尝试过使用专用的集成测试配置文件?另外,既然你从配置中返回的是一个模拟,为什么不在你的测试类中使用
@MockBean? -
@DoeJohnson:以
MockBean的身份注入bean 解决了问题,因为我可以在设置中定义模拟行为并且只使用一个TestConfiguration。
标签: java spring-boot testing dependency-injection integration-testing