【问题标题】:Spring WebFlux - testing RestController with interval responseSpring WebFlux - 使用间隔响应测试 RestController
【发布时间】:2018-03-09 16:57:01
【问题描述】:

我很难为 webflux 控制器创建一个有效的测试,该控制器每隔一秒返回一个 Flux。在我的许多尝试中,我可能已经接近了几次,但总是有一些问题,我无法偶然找到解决方案。

控制器:

@RestController
public class SWFluxDemoController {

    @Autowired
    SWFluxDemoService swFluxDemoService;

    // Messages are Sent to the client as Server Sent Events
    @GetMapping(value = "/", produces = MediaType.TEXT_HTML_VALUE)
    public Flux<String> pushEventSignal() {
        return swFluxDemoService.getInfinityString();
    }

}

服务:

@Service
public class SWFluxDemoService {

    public Flux<String> getInfinityString() {

        Flux<Long> interval = Flux.interval(Duration.ofSeconds(1));
        interval.subscribe((i) -> generateNewMessage());
        Flux<String> messageFlux = Flux.fromStream(
            Stream.generate(() -> generateNewMessage()));

        return Flux.zip(interval, messageFlux).map(Tuple2::getT2);

    }

    private String generateNewMessage() {
        Date theDate = new Date();
        String newMessage = "Updated response at: " + theDate.toString() + "<BR>";
        return newMessage;

    }
}

网络客户端:

public class SimpleFluxClient {
    public static void main(String[] args) throws InterruptedException {
        WebClient webClient = WebClient.create("http://localhost:8080");
        Mono<String> result = webClient.get().retrieve().bodyToMono(String.class);

    }

}

如果我在命令行上使用 mvn spring-boot:run 运行它,然后在浏览器中点击 url localhost:8080,我会得到响应:

Updated response at: Wed Mar 07 16:09:55 EST 2018
Updated response at: Wed Mar 07 16:09:56 EST 2018
Updated response at: Wed Mar 07 16:09:57 EST 2018
Updated response at: Wed Mar 07 16:09:58 EST 2018

这就是我想要的。

问题是在 Spring Tool Suite 中编写和执行测试。我想做类似于以下的事情,但这不会通过语法检查,更不用说运行了。

@RunWith(SpringRunner.class)
@ContextConfiguration(classes={SWFluxDemoController.class,SWFluxDemoService.class})
@WebFluxTest(controllers=SWFluxDemoController.class)
public class SimpleWebFluxDemoApplicationTests {


    @Autowired
    private WebTestClient webClient;

    @Test
    public void get() throws Exception{

        FluxExchangeResult<String> result = webClient.get().uri("/").accept(MediaType.TEXT_EVENT_STREAM)
        .exchange()
 //       .expectStatus().isCreated()
        .returnResult(String.class);        


        StepVerifier.withVirtualTime({ result })
                .expectSubscription()
                .thenAwait(Duration.ofSeconds(1))
                .expectNext(0);

    }
}

使用注释掉的 StepVerifier 代码对 webclient 调用的任何预期状态进行编码会返回 错误 No content available。

非常感谢任何帮助。

【问题讨论】:

    标签: java spring spring-webflux junit5 web-client


    【解决方案1】:

    你的控制器声明它产生 TEXT_HTML_VALUE;而您的测试声明它接受 TEXT_EVENT_STREAM

    这就是导致 406 响应代码的原因。

    因此,您需要确保 producesaccepts 媒体类型兼容。

    【讨论】:

    • 单元测试中的响应类型是 FluxExchangeResult 它需要 TEXT_EVENT_STREAM 媒体类型,这是接收类查看端点的方式。我从值 TEXT_HTML_VALUE 开始,并在我的 IDE 中显示错误: WebTestClient.RequestHeadersSpec 类型中的方法 accept(MediaType...) 不适用于参数 (String)。工作单元测试已作为解决方案发布。
    • 好的。很高兴你解决了!
    【解决方案2】:

    在闲逛之后,我终于找到了解决方案。我的测试结果如下:

        @Test
        public void get() throws Exception{
    
    
    
     FluxExchangeResult<String> result = webClient.get().uri("/").accept(MediaType.TEXT_EVENT_STREAM)
            .exchange()
          .returnResult(String.class);
    
        Flux<String> intervalString = result.getResponseBody();
    
            StepVerifier.create(intervalString)        
                    .expectSubscription()
                    .thenAwait(Duration.ofSeconds(1))
                    .expectNextCount(0)
            .thenAwait(Duration.ofSeconds(1))
            .expectNextCount(1)
            .thenAwait(Duration.ofSeconds(1))
            .expectNextCount(2);        
        }
    

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-31
      • 2022-07-11
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      相关资源
      最近更新 更多