使用直接通道测试错误处理,并使用轮询器测试源

时间:2019-04-23 11:51:57

标签: spring junit error-handling spring-integration spring-integration-dsl

我在Spring Integration DSL中实现了以下流程:

  1. 从HTTP获取提要
  2. 丰富 errorChannel 标头(此处是在下游处理所有异常的点)。
  3. 将邮件转换为收藏夹
  4. 将集合拆分为单独的邮件
  5. 将每条消息发送到下一个处理通道
@Bean
    public IntegrationFlow inboundHttpFlow(
        Puller puller,
        HeaderEnricher errorHandlingChannelHeaderEnricher,
        FeedTransformer feedTransformer,
        MessageChannel outputFeedIntegrationChannel
    ) {
        final Consumer<SourcePollingChannelAdapterSpec> pollingSpec = spec ->
            spec
                .poller(Pollers.cron(SCHEDULE_EVERY_HALF_MINUTE)
                    .errorChannel(INBOUND_ERROR_CHANNEL));

        return IntegrationFlows
            .from(puller, pollingSpec)
            .enrichHeaders(errorHandlingChannelHeaderEnricher)
            .transform(feedTransformer)
            .split()
            .channel(outputFeedIntegrationChannel)
            .get();
    }

我的errorHandlingChannelHeaderEnricher在哪里:

@Component
public class ErrorHandlingChannelHeaderEnricher implements HeaderEnricher {
    @Override
    public void accept(HeaderEnricherSpec spec) {
        spec.header(
            MessageHeaders.ERROR_CHANNEL,
            INBOUND_ERROR_CHANNEL,
            true
        );
    }
}

feedTransformer 在正在运行的应用中引发异常时,它将按预期设置 errorChannel 。但是我不知道如何编写测试以测试引发的异常是否进入标头中定义的 errorChannel

当我尝试以给定方式测试它时,它不起作用,因为异常被抛回到调用者而不是 errorChannel

// given
Throwable transformerException = new IllegalStateException();
when(feedTransformerMock.apply(any())).thenThrow(transformerException);

// when
var testFeedMessage = MessageBuilder
    .withPayload(pullerResult)
    .build();

inboundHttpFlow.getInputChannel().send(testFeedMessage); // excetpion returns to caller here

// then
verify(errorHandlerSpy).accept(transformerException);

异常是典型的:

org.springframework.integration.transformer.MessageTransformationException: Failed to transform Message; nested exception is org.springframework.messaging.MessageHandlingException: nested exception is java.lang.IllegalStateException, failedMessage=GenericMessage [payload=test-payload, headers={errorChannel=inboundErrorChannel, id=f77a6a01-9bca-5af3-8352-7edb4c5e94b0, timestamp=1556019833867}]
, failedMessage=GenericMessage [payload=test-payload, headers={errorChannel=inboundErrorChannel, id=f77a6a01-9bca-5af3-8352-7edb4c5e94b0, timestamp=1556019833867}]

我认为,由于本测试示例中的 DirectChannel 和缺乏轮询器,因此与实际流量(带有轮询器)相比。 有什么方法可以模拟抛出异常并检查它是否真的进入了标头中定义的errorChannel?

1 个答案:

答案 0 :(得分:1)

不清楚您要测试什么。

为什么需要测试框架?

由于轮询器上已经具有错误通道,因此无需填充标题。

您是正确的;发送给... let elem = { title: this.title, message: this.message } this.alerts.push(alert); setTimeout(() => { this.alerts.splice(this.alerts.indexOf(alert), 1); }, this.getTimer(this.message)); ... 会导致异常抛出给调用者。

如果您真的想测试框架,请模拟DirectChannel而不是发送到输入通道。