Spring集成:如果同时执行,测试方法将失败
我的应用程序的工作流程是添加一个消息头,然后根据另一个消息头路由消息,并将消息发送到更远的下游。我对该工作流的测试单独成功,但在一起执行时不会成功,尽管我似乎已重置了所有相关对象 spring集成工作流:Spring集成:如果同时执行,测试方法将失败,spring,unit-testing,spring-integration,Spring,Unit Testing,Spring Integration,我的应用程序的工作流程是添加一个消息头,然后根据另一个消息头路由消息,并将消息发送到更远的下游。我对该工作流的测试单独成功,但在一起执行时不会成功,尽管我似乎已重置了所有相关对象 spring集成工作流: <int:header-enricher input-channel="workflowStart" output-channel="headerEnriched"> <int:header name="correlationId" expression="heade
<int:header-enricher input-channel="workflowStart" output-channel="headerEnriched">
<int:header name="correlationId" expression="headers.id.toString()" />
</int:header-enricher>
<int:header-value-router input-channel="headerEnriched" header-name="messageType">
<int:mapping value="stp" channel="stpChannel" />
<int:mapping value="nonStp" channel="nonStpChannel" />
</int:header-value-router>
<int:publish-subscribe-channel id="nonStpChannel" />
<int:publish-subscribe-channel id="stpChannel" apply-sequence="true"/>
<int:chain input-channel="nonStpChannel" output-channel="systemChannel1" id="nonStpChainBlockA">
<!-- do something -->
</int:chain>
<int:chain input-channel="stpChannel" output-channel="systemChannel3" id="stpChainBlockA">
<!-- do something -->
</int:chain>
Java测试类:
@Autowired
private MessageChannel workflowStart;
@Autowired
private MessageHandler systemChannel1OutputHandler;
@Autowired
private MessageHandler systemChannel3OutputHandler;
@Value("/xml/tradeStp.xml")
private Resource stpMessageResource;
private String stpMessage;
@Value("/xml/tradeNonStp.xml")
private Resource nonStpMessageResource;
private String nonStpMessage;
@Before
public void setup() throws Exception {
reset(systemChannel1OutputHandler);
reset(systemChannel3OutputHandler);
stpMessage = IOUtils.toString(stpMessageResource.getInputStream());
nonStpMessage = IOUtils.toString(nonStpMessageResource.getInputStream());
}
@Test
public void nonStpMessageWorkflow1Test() {
Message<String> m = MessageBuilder
.withPayload(nonStpMessage)
.setHeaderIfAbsent("messageType", "nonStp")
.build();
workflowStart.send(m);
verify(systemChannel1OutputHandler, times(1)).handleMessage(any(Message.class));
}
@Test
public void stpMessageWorkflow2Test() {
Message<String> m = MessageBuilder
.withPayload(stpMessage)
.setHeaderIfAbsent("messageType", "stp")
.build();
workflowStart.send(m);
verify(systemChannel3OutputHandler, times(1)).handleMessage(any(Message.class));
}
以及测试上下文:
<import resource="classpath:/spring/workflow.xml"/>
<int:outbound-channel-adapter channel="systemChannel1" ref="systemChannel1OutputHandler" method="handleMessage"/>
<bean id="systemChannel1OutputHandler" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="org.springframework.integration.core.MessageHandler"/>
</bean>
<int:outbound-channel-adapter channel="systemChannel3" ref="systemChannel3OutputHandler" method="handleMessage"/>
<bean id="systemChannel3OutputHandler" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="org.springframework.integration.core.MessageHandler"/>
</bean>
<int:outbound-channel-adapter channel="headerEnriched" ref="headerEnricherOutputHandler" method="handleMessage"/>
<bean id="headerEnricherOutputHandler" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="org.springframework.integration.core.MessageHandler"/>
</bean>
如果同时运行两个测试,则第一个测试成功,而第二个测试失败,并显示以下消息:
Wanted but not invoked:
messageHandler.handleMessage(<any>);
-> at com.company.integration.com.company.export.config.InterfaceTest.stpMessageWorkflow2Test(InterfaceTest.java:81)
Actually, there were zero interactions with this mock.
我尝试过用各种方式进行调试。问题似乎就在头值路由器之后和链之前。第二个测试的最后一个调试输出是HeaderRiched通道上的postSend。
欢迎任何建议
更新:
我没有在另一个测试的上下文中包含一个额外的outpurthandler,我现在已经包含了它。通过删除headerEnricherOutputHandler,所有测试都可以正常运行。然而,我仍然不明白为什么在一起运行测试时会出现问题 我在Mockito使用anyclass时遇到问题。你在哪里
verify(systemChannel3OutputHandler, times(1)).handleMessage(any(Message.class));
如果删除该类,例如:
verify(systemChannel3OutputHandler, times(1)).handleMessage(any());
我无法用以下内容重现您的问题,这与您的测试没有实质性差异
<int:header-value-router input-channel="headerEnriched" header-name="messageType">
<int:mapping value="stp" channel="stpChannel" />
<int:mapping value="nonStp" channel="nonStpChannel" />
</int:header-value-router>
<int:publish-subscribe-channel id="nonStpChannel" />
<int:publish-subscribe-channel id="stpChannel" apply-sequence="true"/>
<int:chain input-channel="stpChannel" output-channel="systemChannel1">
<int:transformer expression="'bar'"/>
</int:chain>
<int:chain input-channel="nonStpChannel" output-channel="systemChannel3">
<int:transformer expression="'bar'"/>
</int:chain>
<int:channel id="systemChannel1" />
<int:channel id="systemChannel3" />
<int:outbound-channel-adapter channel="systemChannel1" ref="systemChannel1OutputHandler" method="handleMessage"/>
<bean id="systemChannel1OutputHandler" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="org.springframework.integration.core.MessageHandler"/>
</bean>
<int:outbound-channel-adapter channel="systemChannel3" ref="systemChannel3OutputHandler" method="handleMessage"/>
<bean id="systemChannel3OutputHandler" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="org.springframework.integration.core.MessageHandler"/>
</bean>
这两个测试对我来说都很好。谢谢你的建议。这不起作用,因为问题似乎在spring方面,由于某些原因,消息没有被发送到下游。感谢您的帮助。实际上,我没有将一个bean包含到我的上下文see update中,这导致了问题。但仍不清楚出现此问题的原因。由于您有两个用户订阅了“headerEnriched”,因此默认调度程序将循环重新请求,因此您的第二条测试消息将发送到新适配器。如果您真的打算使用这种双重订阅,则需要将“HeaderRiched”设置为发布-订阅频道。
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class Foo {
@Autowired
private MessageChannel headerEnriched;
@Autowired
private MessageHandler systemChannel1OutputHandler;
@Autowired
private MessageHandler systemChannel3OutputHandler;
@Test
public void test10() {
Message<String> foo = MessageBuilder.withPayload("foo")
.setHeader("messageType", "stp").build();
headerEnriched.send(foo);
verify(systemChannel1OutputHandler).handleMessage(any(Message.class));
}
@Test
public void test30() {
Message<String> foo = MessageBuilder.withPayload("foo")
.setHeader("messageType", "nonStp").build();
headerEnriched.send(foo);
verify(systemChannel3OutputHandler).handleMessage(any(Message.class));
}
}