0

我很难为 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 调用的任何预期状态进行编码会返回 <406> 错误 No content available。

非常感谢任何帮助。

4

2 回答 2

2

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

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

因此,您需要确保生产接受媒体类型兼容。

于 2018-03-10T16:23:07.730 回答
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);        
    }
于 2018-03-10T16:27:45.917 回答