【问题标题】:Testing error flows with Spring Cloud Streams使用 Spring Cloud Streams 测试错误流
【发布时间】:2020-02-24 13:41:58
【问题描述】:

我已经使用 Spring Cloud Streams 启动了一个小型微服务。

我只有两个流绑定如下:

 cloud:
    stream:
      bindings:
        channelone:
          destination: org.queue.app.EventsOne
          contentType: application/json
          group: app
        channeltwo:
          destination: org.queue.app.EventsTwo
          contentType: application/json
          group: app

我使用 Serenity 开发了组件测试,并将通道注入到我想要发送测试消息的位置:


@Autowired
@Qualifier(Channels.EVENTS_ONE_CHANNEL)
SubscribableChannel eventsOneChannel

@Autowired
@Qualifier(Channels.EVENTS_TWO_CHANNEL) 
SubscribableChannel eventsTwoChannel

地点:

Channels.EVENTS_ONE_CHANNEL and EVENTS_TWO_CHANNEL 

只是定义为字符串常量:

@UtilityClass
public class Channels {
    public static final String EVENTS_ONE_CHANNEL= "channelone";
    public static final String EVENTS_TWO_CHANNEL= "channeltwo";
}

组件测试模块导入依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-stream-test-support</artifactId>
</dependency>

我正在发送如下消息:

eventsOneChannel.send(someMessage)

快乐的流程运行良好。但是,当侦听器无法处理消息时,我想测试错误流。

这是一个监听器的例子:

@StreamListener(Channels.EVENTS_ONE_CHANNEL)
@SendTo(Channels.DTO_GENERATED)
public BonusDTO receive(Message<String> message) {
    try {
        log.info("Received Event event with payload [{}]", message.getPayload());
        return toDto(message.getPayload());
    } catch (Exception ex) {
        log.error("Error converting Event to DTO", ex);
        throw new EventHandlingException(ex);
    }
}

当 try/catch 抛出异常时,错误由服务激活器处理:

@ServiceActivator(inputChannel = "org.queue.app.EventsOne.app.errors")
public void handle(ErrorMessage errorMessage) {
   log.info("Error");
}

在没有 spring-cloud-stream-test 的情况下运行应用程序时,如果发生错误处理消息,则会触发先前的服务激活并处理错误。

但是,在测试期间不会发生同样的情况。使用 spring-cloud-stream-test,当监听器抛出异常时,从错误通道激活的服务不会被调用。

我也想测试错误流。

这是 spring-cloud-stream-test 的限制吗?使用 spring-cloud-stream-test 时有任何配置、技巧或提示,以将错误消息发送到错误通道?

谢谢

【问题讨论】:

    标签: java spring spring-boot spring-integration spring-cloud-stream


    【解决方案1】:

    @Joao Pereira 我认为这里有一个更大的问题,所以我会尝试把它列出来,希望能提供一些清晰

    1. 能够使用 ServiceActivator 注释错误处理程序方法是框架提供的合同,这意味着它的测试是我们的责任。此外,您使用的机制甚至不是来自 Spring Cloud Stream,而是来自 Spring Integration。但无论如何,我质疑应用程序是否应该测试它,因为你不能在应用程序级别以任何方式影响它,因为它不是你的功能。 同样,这是我的观点,我很想看看你的想法。

    2. 在 Spring Cloud Stream 3.0.0.RC1(和后续版本)中,我们有效地弃用了 spring-cloud-stream-test-support,转而支持 Gary 提到的 new test binder。我刚刚提供的链接中记录了它的原因,但请随时跟进问题。虽然它的用法有很好的记录,但这里是one of the test cases,我们自己使用它供您参考。尽管参考文档中的示例显示了基于函数的消息处理程序,但它与基于注释的消息处理程序(这是您正在使用的)的工作方式相同。

    3. 谈到基于注解的编程模型,请参阅我们刚刚发布的以下博客(查看更多正在开发的文章),我们将在其中阐述我们为什么要远离基于注解的编程模型和我认为您也应该开始考虑更改代码。毕竟,所有的更改几乎相当于删除所有注释并稍微更改消息处理程序方法的签名以表示为函数 bean

    我之所以这么说的原因很多,但是您上面的代码和您表达的担忧再次提醒我为什么我们要远离这种编程模型。

    我会在这里停下来,因为我相信这里有很多要消化的东西,但是鉴于我刚才所说的内容,请随时跟进更尖锐的问题。

    【讨论】:

    • 感谢您的宝贵时间。关于第 1 点)我问自己同样的问题。我应该将错误处理本身视为一个单独的应用程序吗?流程由 spring 集成管理。快乐流工作正常,激活了正确的服务,所以我想我可以用同样的方式处理错误流......我会寻找 spring 集成测试库,我会在那里找到答案。关于第 3 点)这是个好消息,我会挖掘更多链接。在阅读了您的第二篇文章后,我还意识到有更好的方法可以以更被动的方式实现许多用例。谢谢
    【解决方案2】:

    spring-cloud-stream-test 启用了一个非常基本的测试绑定器;它没有真正的活页夹的所有功能。

    【讨论】:

    • 谢谢加里。我怀疑
    • IIRC,正在开发一个新的测试活页夹;不确定它的状态。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-16
    • 2021-10-26
    • 1970-01-01
    • 2020-07-11
    • 2021-05-04
    • 1970-01-01
    • 2019-12-09
    相关资源
    最近更新 更多