1

In Kotlin, I tried to test a simple @RestController using StepVerifier.

  @GetMapping("/helloInt")
  fun helloInt(): Flux<Int> {
    return Flux.range(1, 3).delayElements(Duration.ofMillis(300))
  }

The test is here:

@Test
  fun callingIntEndpoint(){
    var responseBody = webTestClient
      .get()
      .uri("/helloInt")
      .exchange().returnResult<Int>()
    StepVerifier
      .create(responseBody.getResponseBody())
      .expectSubscription()
      .expectNext(1)
      .expectNext(2)
      .expectNext(3)
      .verifyComplete()
  }

And it works just fine. However, when I tried to test a Flux<String>

@GetMapping("/hello")
  fun hello(): Flux<String> {
    return Flux.just("testing", "hello", "Kotlin")
      .delayElements(Duration.ofMillis(300)) //to make sure they are 3 distinct messages
  }

This Unit Test does NOT fail, and it shows clearly what the problem is:

@Test
  fun callingTheEndpoint() {
    webTestClient
      .get()
      .uri("/hello")
      .exchange()
      .returnResult<String>()
      .responseBody
      .test()
      .expectNextMatches { it.equals("testinghelloKotlin") } // but this is NOT what I actually would want to see
      .verifyComplete()
  }

Why is it that the 3 strings are concatenated? When I open the URL in a browser I clearly see the 3 string one by one.

I would like to make this UT work:

@Test
  fun callingTheEndpoint() {
    webTestClient
      .get()
      .uri("/hello")
      .exchange()
      .returnResult<String>()
      .responseBody
      .test()
      .expectNextMatches { it.equals("testing") }
      .expectNextMatches { it.equals("hello") }
      .expectNextMatches { it.equals("Kotlin") }
      .verifyComplete()  }
Sara Iorgulescu
  • 7
  • 1
  • 1
  • 6
moldovean
  • 3,132
  • 33
  • 36
  • 1
    It is not clear what content-type is used for your test. Do you want your endpoint to send plain text or json ? If you want json, a flux of String should be transformed to an array of string, I think. Try to force the "Accept" header to "application:json" on your webtestclient to check that ? – amanin Dec 22 '22 at 15:16
  • 1
    @amanin you are absolutely correct. it is missing a response content type `@GetMapping("/hello", produces = ["text/event-stream"])` solves the problem – moldovean Dec 22 '22 at 15:18

1 Answers1

0

adding produces = ["text/event-stream"] does the trick

@GetMapping("/hello", produces = ["text/event-stream"])
  fun hello(): Flux<String> {
    return Flux.just("testing", "hello", "Kotlin")
      .delayElements(Duration.ofMillis(300)) //to make sure they are 3 distinct messages
  }
moldovean
  • 3,132
  • 33
  • 36