How to test Server Sent Events API (written in Spring 5 Webflux), when it is necessary to perform action to generate new event?

huangapple 未分类评论44阅读模式
英文:

How to test Server Sent Events API (written in Spring 5 Webflux), when it is necessary to perform action to generate new event?

问题

我正在尝试按照以下教程 https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#webtestclient-stream 中的说明测试我的 SSE API。

不幸的是,对我来说这并不起作用。要生成下一个事件,需要执行一些将触发它的操作。在等待 WebTestClient 的响应时,我无法做到这一点(我没有找到添加这种处理程序的可能性)。

我通过创建一个单独的线程来找到了解决方法,以便定期触发生成事件,但这并不优雅。有没有更好的方法来做到这一点?

TimerTask task = new TimerTask() {
public void run() {
while (true) {
// 触发定期生成事件的代码
}
}
};
Timer timer = new Timer("Timer");
long delay = 1000L;
timer.schedule(task, delay);

FluxExchangeResult result = client.get().uri("/events")
.accept(TEXT_EVENT_STREAM)
.exchange()
.expectStatus().isOk()
.returnResult(MyEvent.class);

Flux eventFlux = result.getResponseBody();

StepVerifier.create(eventFlux)
.expectNext(person)
.expectNextCount(4)
.consumeNextWith(p -> ...)
.thenCancel()
.verify();


<details>
<summary>英文:</summary>

I am trying to test my SSE API in the way explained in the following tutorial https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#webtestclient-stream .

Unfortunately, it doesn&#39;t work for me. To generate next event it is necessary to perform some actions that will trigger it. I couldn&#39;t do it while waiting for response from WebTestClient (I didn&#39;t find the possibility to add such handler).

I found the workaround by creating separate thread that trigger generating events periodically, but it is not elegant. Is there any better way to do it?

TimerTask task = new TimerTask() {
public void run() {
while (true) {
//code that trigger generating event periodically
}
}
};
Timer timer = new Timer("Timer");
long delay = 1000L;
timer.schedule(task, delay);

FluxExchangeResult<MyEvent> result = client.get().uri("/events")
.accept(TEXT_EVENT_STREAM)
.exchange()
.expectStatus().isOk()
.returnResult(MyEvent.class);

Flux<Event> eventFlux = result.getResponseBody();

StepVerifier.create(eventFlux)
.expectNext(person)
.expectNextCount(4)
.consumeNextWith(p -> ...)
.thenCancel()
.verify();




</details>


# 答案1
**得分**: 0

我遇到过类似的问题。如果我理解你的意思正确,你想要发布某种消息,然后检查是否收到了该消息。如果是这种情况,你应该使用订阅并提供消费者。以下是一个示例代码:

```java
FluxExchangeResult<MyEvent> result = client.get().uri("/events")
    .accept(TEXT_EVENT_STREAM)
    .exchange()
    .expectStatus().isOk()
    .returnResult(MyEvent.class)
    .getResponseBody()
    .subscribe(new Consumer<MyEvent>() {
        @Override
        public void accept(MyEvent event) {
            // 在这里处理事件
        }
    });
英文:

I had similar issue. If I understand you correctly, you want to publish some sort of message and then check if you are getting that message or not. If that is the case then you should use subscribe and provide consumer. Here is an example.

FluxExchangeResult&lt;MyEvent&gt; result = client.get().uri(&quot;/events&quot;)
    .accept(TEXT_EVENT_STREAM)
    .exchange()
    .expectStatus().isOk()
    .returnResult(MyEvent.class)
    .getResponseBody()
    .subscribe(new Consumer&lt;MyEvent&gt;() {
        @Override
        public void accept(String event) {
        }
    });

huangapple
  • 本文由 发表于 2020年4月9日 22:56:11
  • 转载请务必保留本文链接:https://java.coder-hub.com/61124065.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定