我正在使用spring boot工作,我们刚刚升级到1.4.0版本.RELEASE。作为版本升级的一部分,我们已经开始在抽象集成测试类中使用@SpringBootTest注释。阅读the documentation之后,听起来我们应该能够使用嵌套的@ TestConfiguration-annotated配置类来覆盖特定测试期间的bean定义。这对我们不起作用,而是我们试图覆盖的非测试bean仍在使用。
有趣的是,似乎模拟测试bean和生产bean的用法实际上是在同一个测试中交织在一起,就像两个bean在应用程序上下文中并排存在一样。此外,似乎集成测试以某种方式运行的顺序会影响此行为。我想知道这是否是我们错误配置的,或者是否还有其他事情发生。
编辑:
集成测试继承的抽象类如下所示:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles({"local", "test"})
public abstract class BaseIntegrationTest {
@Value("${local.server.port}")
protected int port;
}
我们看到奇怪行为的集成测试看起来像这样:
public class WebhookProcessorIT extends BaseIntegrationTest {
@TestConfiguration
public static class Config {
@Bean
@Primary
public WebhookTask webhookTask() {
return mock(WebhookTask.class);
}
}
// sometimes the mock above is used and sometimes
// the actual production bean is used
@Autowired
private WebhookTask task;
@Before
public void setup() {
when(task.process(any())).thenReturn(true);
}
// tests ...
}
这就是根应用程序上下文类的样子:
@EnableAutoConfiguration(exclude = ErrorMvcAutoConfiguration.class)
@SpringBootApplication
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
final SpringApplication app = new SpringApplication(Application.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}
}
编辑:
我也尝试使用@MockBean
,如下所示:
public class WebhookProcessorIT extends BaseIntegrationTest {
@MockBean
private WebhookTask task;
但测试运行时我得到的结果相同。我可以看到Spring在测试设置期间查看日志时尝试使用我提供的模拟覆盖生产bean:
build 15-Sep-2016 09:09:24 2016-09-15 09:09:24 [34mINFO [0;39m [36m[DefaultListableBeanFactory][0;39m (main) Overriding bean definition for bean 'productionWebhookTask' with a different definition
然而,当涉及到测试执行时,我仍然可以看到正在使用的生产bean:
build 15-Sep-2016 09:09:29 2016-09-15 09:09:29 [39mDEBUG[0;39m [36m[WebhookSupplier][0;39m (WebhookProcessor) Received webhook with ID '1234' from queue.
build 15-Sep-2016 09:09:30 2016-09-15 09:09:30 [39mDEBUG[0;39m [36m[WebhookSupplier][0;39m (WebhookProcessor) Received webhook with ID '5678' from queue.
build 15-Sep-2016 09:09:30 2016-09-15 09:09:30 [39mDEBUG[0;39m [36m[ProductionWebhookTask][0;39m (WebhookProcessor) Received webhook with ID '1234' for processing // production webhook task bean still being used for webhook '1234'
build 15-Sep-2016 09:09:30 2016-09-15 09:09:30 [39mDEBUG[0;39m [36m[WebhookSupplier][0;39m (WebhookProcessor) Deleting webhook with id '5678' from queue. // mock bean causes production logic to be skipped and we just delete webhook '5678'
// More logs from production webhook task operating on webhook with id '1234' and causing the test to fail
答案 0 :(得分:0)
无论如何,您可以使用 @Profile(" test")和使用@Profile(" production")的真实注释来为您的测试bean添加注释
并在您的属性文件中输入属性 spring.profiles.active = test
来自文档
与常规@Configuration类不同,使用@TestConfiguration 不会阻止自动检测@SpringBootConfiguration。
与嵌套的@Configuration类不同,后者将用于代替 应用程序的主要配置,嵌套的@TestConfiguration 除了应用程序的主要内容之外,还将使用class 配置。
答案 1 :(得分:0)
由于您使用的是Spring Boot 1.4.0版,因此您可以继续使用新引入的注释 @MockBean ,而不是使用不同的配置类来模拟原始bean。它很直接,非常适合您的使用案例。