【发布时间】:2016-09-17 12:56:42
【问题描述】:
我正在使用 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 正在尝试使用我提供的 mock 覆盖生产 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
【问题讨论】:
-
你的意思是偶尔运行一个真正的bean而不是模拟的bean还是什么?
-
您能否分享您的测试课程,以便我们了解您的具体设置的更多信息?
-
@ShadyRagab 是的,看起来是这样。
-
@enbdk 运行两个配置类会有点棘手,因为 TestConfiguration 不会替换生产类。它们都将在上下文中。
-
@enbdk 我不太了解日志行,但您是否也会提供您的方法存根和期望?
标签: spring-boot