2012-11-13 52 views
0

我的应用程序的工作流程是添加一个消息头,然后根据另一个头路由消息并在下游发送消息。我对这个工作流的测试单独成功,但不是在一起执行时,尽管看起来我重置了所有相关对象。弹簧集成:如果一起执行测试方法失败

Spring集成的工作流程:

<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. 

我试图以各种方式进行调试。这个问题似乎是在标题值路由器之后和链之前。第二个测试的最后一个调试输出是headerEnriched通道上的“postSend”。 任何建议是非常受欢迎的。

更新: 我没有包括一个额外的outputHandler,我已经在我的上下文中进行了另一个测试,现在我已经包含了这个测试。通过删除headerEnricherOutputHandler所有测试运行良好。但是,当测试一起运行时,我仍然不明白这会导致问题的原因。

回答

0

我遇到过使用任何(类)Mockito的问题。当你有

verify(systemChannel3OutputHandler, times(1)).handleMessage(any(Message.class)); 

它用,如果你删除类,如工作:

verify(systemChannel3OutputHandler, times(1)).handleMessage(any()); 
+0

感谢您的想法。这不起作用,因为问题似乎在春季,由于某种原因,邮件没有被发送到下游。 – evgeni

0

我不能跟以下,这似乎并没有你的测试存在重大差异重现您的问题...

<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> 

@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)); 
    } 
} 

这两个测试对我来说运行良好。

+0

感谢您的帮助。实际上,我没有将一个bean包含到我的上下文中(请参阅更新),这导致了问题。仍然不清楚为什么问题出现。 – evgeni

+1

由于您有两个消费者订阅了'headerEnriched',因此默认的调度程序将对reequest进行循环,因此您的第二个测试消息会发送到“新”适配器。如果您真的希望这种双重订阅,您需要将'headerEnriched'设为发布 - 订阅频道。 –