单元测试Spring Integration flow DSL

时间:2017-05-17 21:51:19

标签: spring-integration spring-boot-test

我正在尝试对一个简单的流进行单元测试,检查文件是否存在,然后执行一些额外的任务。

IntegrationFlow

@Bean
public IntegrationFlow initiateAlarmAck() {
    return IntegrationFlows.from("processAckAlarmInputChannel")
            .handle((payload, headers) ->  {
                LOG.info("Received initiate ack alarm request at " + payload);
                File watermarkFile = getWatermarkFile();
                if(watermarkFile.isFile()){
                    LOG.info("Watermark File exists");
                    return true;
                }else{
                    LOG.info("File does not exists");
                    return false;
                }
            })
            .<Boolean, String>route(p -> fileRouterFlow(p))
            .get();
}
File getWatermarkFile(){
    return new File(eventWatermarkFile);
}

@Router
public String fileRouterFlow(boolean fileExits){
    if(fileExits)
        return "fileFoundChannel";
    else
        return "fileNotFoundChannel";
}

还有另一个集成流程,它从fileNotFoundChannel中选择一条消息并进行其他处理。我不想对这部分进行单元测试。如何在fileNotFoundChannel上发送消息后停止我的测试,不再做进一步停止?

@Bean
public IntegrationFlow fileNotFoundFlow() {
    return IntegrationFlows.from("fileNotFoundChannel")
            .handle((payload, headers) ->  {
                LOG.info("File Not Found");
                return payload;
            })
            .handle(this::getLatestAlarmEvent)
            .handle(this::setWaterMarkEventInFile)
            .channel("fileFoundChannel")
            .get();
}

单元测试类

@RunWith(SpringRunner.class)
@Import(AcknowledgeAlarmEventFlow.class)
@ContextConfiguration(classes = {AlarmAPIApplication.class})
@PropertySource("classpath:application.properties ")
public class AcknowledgeAlarmEventFlowTest {


    @Autowired
    ApplicationContext applicationContext;

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    @Qualifier("processAckAlarmInputChannel")
    DirectChannel processAckAlarmInputChannel;

    @Autowired
    @Qualifier("fileNotFoundChannel")
    DirectChannel fileNotFoundChannel;

    @Autowired
    @Qualifier("fileFoundChannel")
    DirectChannel fileFoundChannel;

    @Mock
    File mockFile;

    @Test
    public void initiateAlarmAck_noFileFound_verifyMessageOnfileNotFoundChannel(){


        AcknowledgeAlarmEventFlow.ProcessAcknowledgeAlarmGateway gateway = applicationContext.getBean(AcknowledgeAlarmEventFlow.ProcessAcknowledgeAlarmGateway.class);
        gateway.initiateAcknowledgeAlarm();

        processAckAlarmInputChannel.send(MessageBuilder.withPayload(new Date()).build());
        MessageHandler mockMessageHandler = mock(MessageHandler.class);

        fileNotFoundChannel.subscribe(mockMessageHandler);
        verify(mockMessageHandler).handleMessage(any());
    }
}

提前致谢

1 个答案:

答案 0 :(得分:3)

这正是我们now实施https://laravel.com/docs/5.4/mail#queueing-mail的情况。

看起来你正确地采用嘲讽来阻止MockMessageHandler中的进一步行动,但是错过了一些简单的技巧:

您必须fileNotFoundFlow stop()上的真实.handle((payload, headers) )端点。这样它就会取消订阅频道,不再消费消息。为此,我建议:

fileNotFoundChannel

在测试课中

    return IntegrationFlows.from("fileNotFoundChannel")
           .handle((payload, headers) ->  {
                LOG.info("File Not Found");
                return payload;
            }, e -> e.id("fileNotFoundEndpoint"))

支付,请注意,在向频道发送消息之前,我是如何移动模拟和订阅的。

使用新的 @Autowired @Qualifier("fileNotFoundEndpoint") AbstractEndpoint fileNotFoundEndpoint; ... @Test public void initiateAlarmAck_noFileFound_verifyMessageOnfileNotFoundChannel(){ this.fileNotFoundEndpoint.stop(); MessageHandler mockMessageHandler = mock(MessageHandler.class); fileNotFoundChannel.subscribe(mockMessageHandler); AcknowledgeAlarmEventFlow.ProcessAcknowledgeAlarmGateway gateway = applicationContext.getBean(AcknowledgeAlarmEventFlow.ProcessAcknowledgeAlarmGateway.class); gateway.initiateAcknowledgeAlarm(); processAckAlarmInputChannel.send(MessageBuilder.withPayload(new Date()).build()); verify(mockMessageHandler).handleMessage(any()); } 功能,框架将为您处理这些内容。但是......就像任何单元测试一样,模拟必须在交互之前做好准备。

<强>更新

工作样本:

MockIntegrationContext