简体   繁体   中英

Spring WebFlux - testing RestController with interval response

I'm having difficulty in creating a valid test for a webflux controller that returns a Flux on one second intervals. I have probably been close a couple of times in my many attempts, but there is always something amiss and I haven't been able to stumble upon a solution.

The controller:

@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();
    }

}

The Service:

@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;

    }
}

The Web Client:

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);

    }

}

If I run this on the command line with mvn spring-boot:run and then hit the url localhost:8080 in my browser, I will get the response:

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

which is what I want.

The issue is writing and executing a test in the Spring Tool Suite. I want to do something similar to the following, but this won't pass a syntax check let alone run.

@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);

    }
}

Coding any expected status for the webclient call with the StepVerifier code commented out returns a <406> error No content available.

Any help greatly appreciated.

Your controller declares that it produces TEXT_HTML_VALUE ; whereas, your test declares that it accepts TEXT_EVENT_STREAM .

That's what leads to the 406 response code.

So you'll need to ensure that the produces and accepts media types are compatible.

After mucking around I finally arrived at a solution. My test ended up as follows:

    @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);        
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM