Spring集成:如何对轮询器建议进行单元测试

Spring集成:如何对轮询器建议进行单元测试,spring,spring-integration,spring-integration-dsl,Spring,Spring Integration,Spring Integration Dsl,我正在尝试对轮询器上的一条建议进行单元测试,该建议会阻止mongo通道适配器的执行,直到满足某个条件(=处理此批处理中的所有消息) 流程如下所示: IntegrationFlows.from(MongoDb.reactiveInboundChannelAdapter(mongoDbFactory, new Query().with(Sort.by(Sort.Direction.DESC, "modifiedDate")).limit(1))

我正在尝试对轮询器上的一条建议进行单元测试,该建议会阻止mongo通道适配器的执行,直到满足某个条件(=处理此批处理中的所有消息)

流程如下所示:

IntegrationFlows.from(MongoDb.reactiveInboundChannelAdapter(mongoDbFactory,
            new Query().with(Sort.by(Sort.Direction.DESC, "modifiedDate")).limit(1))
                    .collectionName("metadata")
                    .entityClass(Metadata.class)
                    .expectSingleResult(true),
            e -> e.poller(Pollers.fixedDelay(Duration.ofSeconds(pollingIntervalSeconds))
                    .advice(this.advices.waitUntilCompletedAdvice())))
            .handle((p, h) -> {
                this.advices.waitUntilCompletedAdvice().setWait(true);
                return p;
            })
            .handle(doSomething())
            .channel(Channels.DOCUMENT_HEADER.name())
            .get();
以及以下建议:

@Bean
public WaitUntilCompletedAdvice waitUntilCompletedAdvice() {
    DynamicPeriodicTrigger trigger = new DynamicPeriodicTrigger(Duration.ofSeconds(1));
    return new WaitUntilCompletedAdvice(trigger);
}
建议本身:

public类waituntlcompletedadvice扩展了SimpleActivityMessageSourceAdvice{
AtomicBoolean等待=新的AtomicBoolean(false);
公共等待完成通知(DynamicPeriodicTrigger触发器){
超级(触发器);
}
@凌驾
接收前公共布尔值(MessageSource){
if(getWait())
返回false;
返回true;
}
公共布尔getWait(){
返回wait.get();
}
公共void setWait(布尔newWait){
if(getWait()==newWait)
返回;
while(true){
if(wait.compareAndSet(!newWait,newWait)){
返回;
}
}
}
}
我使用以下测试来测试流:

@测试
public void TestClainPollingAdapterFlow()引发异常{
//给定
参数捕获器
itf.getInputChannel().send(新的GenericMessage(Mono.just(data));

它绕过轮询器直接发送消息

您可以通过在测试中调用
beforeceive()
对已配置的通知进行单元测试

或者您可以使用相同的建议创建虚拟测试流

IntegationFlows.from(() -> "foo", e -> e.poller(...))
       ...
并验证只发送了一条消息

itf.getInputChannel().send(新的GenericMessage(Mono.just(data));

它绕过轮询器直接发送消息

您可以通过在测试中调用
beforeceive()
对已配置的通知进行单元测试

或者您可以使用相同的建议创建虚拟测试流

IntegationFlows.from(() -> "foo", e -> e.poller(...))
       ...

并验证只发送了一条消息。

示例实现:

@Test
public void testWaitingActivate() {
    // given
    this.advices.waitUntilCompletedAdvice().setWait(true);

    // when
    Message<ProcessingMetadata> receive = (Message<ProcessingMetadata>) testChannel.receive(3000);

    // then
    assertThat(receive).isNull();
}

@Test
public void testWaitingInactive() {
    // given
    this.advices.waitUntilCompletedAdvice().setWait(false);

    // when
    Message<ProcessingMetadata> receive = (Message<ProcessingMetadata>) testChannel.receive(3000);

    // then
    assertThat(receive).isNotNull();
}

@Configuration
@EnableIntegration
public static class Config {

    @Autowired
    private Advices advices;

    @Bean
    public PollableChannel testChannel() {
        return new QueueChannel();
    }

    @Bean
    public IntegrationFlow fakeFlow() {
        this.advices.waitUntilCompletedAdvice().setWait(true);
        return IntegrationFlows.from(() -> "foo", e -> e.poller(Pollers.fixedDelay(Duration.ofSeconds(1))
                .advice(this.advices.waitUntilCompletedAdvice()))).channel("testChannel").get();
    }
}
@测试
public void testWaitingActivate(){
//给定
this.advices.waituntlcompletedadvice().setWait(true);
//什么时候
Message receive=(Message)testChannel.receive(3000);
//然后
assertThat(receive.isNull();
}
@试验
public void testwaitingactive(){
//给定
this.advices.waituntlcompletedadvice().setWait(false);
//什么时候
Message receive=(Message)testChannel.receive(3000);
//然后
assertThat(receive.isNotNull();
}
@配置
@使能集成
公共静态类配置{
@自动连线
私人意见;
@豆子
公共可轮询频道testChannel(){
返回新的队列通道();
}
@豆子
公共集成流fakeFlow(){
this.advices.waituntlcompletedadvice().setWait(true);
返回IntegrationFlows.from(()->“foo”,e->e.poller(Pollers.fixedDelay(持续时间秒(1))
.advice(this.advices.waituntlcompletedadvice()).channel(“testChannel”).get();
}
}

实施示例:

@Test
public void testWaitingActivate() {
    // given
    this.advices.waitUntilCompletedAdvice().setWait(true);

    // when
    Message<ProcessingMetadata> receive = (Message<ProcessingMetadata>) testChannel.receive(3000);

    // then
    assertThat(receive).isNull();
}

@Test
public void testWaitingInactive() {
    // given
    this.advices.waitUntilCompletedAdvice().setWait(false);

    // when
    Message<ProcessingMetadata> receive = (Message<ProcessingMetadata>) testChannel.receive(3000);

    // then
    assertThat(receive).isNotNull();
}

@Configuration
@EnableIntegration
public static class Config {

    @Autowired
    private Advices advices;

    @Bean
    public PollableChannel testChannel() {
        return new QueueChannel();
    }

    @Bean
    public IntegrationFlow fakeFlow() {
        this.advices.waitUntilCompletedAdvice().setWait(true);
        return IntegrationFlows.from(() -> "foo", e -> e.poller(Pollers.fixedDelay(Duration.ofSeconds(1))
                .advice(this.advices.waitUntilCompletedAdvice()))).channel("testChannel").get();
    }
}
@测试
public void testWaitingActivate(){
//给定
this.advices.waituntlcompletedadvice().setWait(true);
//什么时候
Message receive=(Message)testChannel.receive(3000);
//然后
assertThat(receive.isNull();
}
@试验
public void testwaitingactive(){
//给定
this.advices.waituntlcompletedadvice().setWait(false);
//什么时候
Message receive=(Message)testChannel.receive(3000);
//然后
assertThat(receive.isNotNull();
}
@配置
@使能集成
公共静态类配置{
@自动连线
私人意见;
@豆子
公共可轮询频道testChannel(){
返回新的队列通道();
}
@豆子
公共集成流fakeFlow(){
this.advices.waituntlcompletedadvice().setWait(true);
返回IntegrationFlows.from(()->“foo”,e->e.poller(Pollers.fixedDelay(持续时间秒(1))
.advice(this.advices.waituntlcompletedadvice()).channel(“testChannel”).get();
}
}

谢谢Gary!我喜欢单独虚拟测试的想法,但如何向该流发送消息,而不是getInputChannel()。发送?不清楚您的意思-该虚拟流将发送一条负载为“foo”的消息在每次轮询中,除非通知取消轮询。如果下游流调用通知停止轮询,您将只收到一条消息。谢谢,我想我现在已经收到了。我将测试它并返回给您。谢谢Gary!我喜欢单独的虚拟测试,但如何向该流发送除getInputChannel()之外的消息.send?不清楚您的意思-除非通知取消了轮询,否则虚拟流将在每次轮询时发送一条有效负载为“foo”的消息。如果下游流调用通知停止轮询,您将只收到一条消息。谢谢,我想我现在已经收到了。我将测试它并返回给您。