我有一个 Spring Integration 流程,它利用
MessageSource
定期填充来自数据库查询的消息(不,我不打算使用 Spring Integration JPA/JDBC)
@Bean
public IntegrationFlow messageTimeout(
ReadTimeoutsMessageSource readTimeoutsMessageSource,
UpdatePaymentWithStatusTimeoutHandler updatePaymentWithStatusTimeoutHandler
) {
return IntegrationFlow
/*
* Read from OraIpTask procedure
*/
.from(readTimeoutsMessageSource, s -> s
.id("messageTimeout.readTimeouts")
.poller(Pollers.fixedDelay(Duration.ofMinutes(1), Duration.ofSeconds(10)))
)
.split(s -> s.requiresReply(false))
.bridge(b -> b
.id("messageTimeout.bridge")
.taskScheduler(messageTimeoutScheduler())
)
/*
* Log a warning
*/
.log(LoggingHandler.Level.WARN, dto -> "Found timeout: " + dto)
/*
Update Payment with status timeout
*/
.handle(updatePaymentWithStatusTimeoutHandler, h -> h.id("updatePaymentWithStatusTimeoutFlow.updatePaymentWithStatusTimeout"))
/*
Discard the message
*/
.nullChannel();
}
让我们进入正题:轮询器的初始延迟为 10 秒,在该流程的 Junit 测试中我不想等待宝贵的时间。
测试模拟一个存储过程来返回数据,我希望相应地构造一条消息。我只是想测试消息中的每一行是否都被最后的
handler
所消耗,而无需等待。
有没有办法告诉Spring在测试期间立即启动轮询器和/或运行一次?
作为替代方案,我可以自己构建消息并将
MockIntegrationContext.substituteMessageSourceFor
与模拟消息一起使用。我还没试过。我要求了解有关 Spring Integration 的更多信息以及执行自动化测试的最简洁方法
谢谢您的建议!
现在的方法是这样的:
您用
@SpringIntegrationTest(noAutoStartup ="messageTimeout.readTimeouts")
标记您的测试课程。
即使您不使用模拟,您仍然希望控制 SourcePollingChannelAdapter
生命周期:为轮询器准备过程和相应的触发器。因此,最好在准备好测试之前停止该端点。
你在测试课上所做的:
@Autowired
@Qualifier("messageTimeout.readTimeouts")
SourcePollingChannelAdapter readTimeoutsEndpoint;
在测试方法(或如何准备测试数据)中,您需要:
this.readTimeoutsEndpoint.setTrigger(new OnlyOnceTrigger());
this.readTimeoutsEndpoint.start();
您的数据消耗将立即发生。
我认为我们可以引入类似
MockIntegrationContext.substituteTriggerFor(String pollingAdapterId, Trigger trigger, boolean autoStartup)
的内容来使其显而易见。
请随意为此提出 GH 问题!现在我相信你给你的解决方案就是你正在寻找的。