Spring Boot WebFlux test not finding MockMvc

As pointed out by M. Deinum MockMvc isn't loaded for the WebFlux configuration in Spring Boot. You need to use WebTestClient instead. So replace AutoConfigureMockMvc with AutoConfigureWebTestClient and utilize the the webTestClient methods in its place.

One thing to note is that this is making actual web calls behind the scenes and will start the server. MockMVC does not start the server. What is the difference between MockMvc and WebTestClient?


As this Question seems to appear at the top of search lists when people are trying to test their endpoints after they've switched to Spring WebFlux, I'll add what I was able to determine here. (It should be noted that in the past I was having an incredibly hard time getting the WebTestClient to function with RestController annotated endpoints. But this code works. I think I was missing a dependency and it wasn't clear.)

MyService.java

@Service
public class MyService {
     public String doSomething(String input) {
         return input + " implementation";
     }
}

MyController.java

@RestController
@RequestMapping(value = "/api/v1/my")
public class MyController {
    @Autowired
    private MyService myService;

    @RequestMapping(value = "", method = RequestMethod.POST, consumes = {APPLICATION_JSON_VALUE})
    public ResponseEntity<Mono<String>> processPost(@RequestBody String input)
    {
        String response = myService.doSomething(input);
        return ResponseEntity.ok(Mono.just(response));
    }

TestMyController.java

@ExtendWith(SpringExtension.class)
@WebFluxTest(MyController.class)
public class TestMyController {
    @Autowired
    private WebTestClient webTestClient;

    @MockBean
    private MyService myService;

    @Test
    public void testPost() throws Exception {
          // Setup the Mock MyService. Note the 'mocked' vs 'implementation' 
          when(myService.doSomething(anyString())).thenAnswer((Answer<String>) invocation -> {
               String input = invocation.getArgument(0);
               return input + " mocked";
          });

          String response = webTestClient.post()
                .uri("/api/v1/my")
                .body(BodyInserters.fromObject("is"))
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                .expectStatus().isOk()
                .returnResult(String.class)
                .getResponseBody()
                .blockFirst();
          assertThat(response).matches("is mocked");
    }
}

The dependencies that can cause issues that are hard to diagnose appear to be from reactor-test. So if the WebTestClient is not working, make sure that dependency exists.

pom.xml

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
        <version>2.1.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>2.1.5.RELEASE</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.projectreactor</groupId>
        <artifactId>reactor-test</artifactId>
        <version>3.2.9.RELEASE</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <artifactId>jackson-module-kotlin</artifactId>
                <groupId>com.fasterxml.jackson.module</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.4.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.google.truth</groupId>
        <artifactId>truth</artifactId>
        <version>0.45</version>
        <scope>test</scope>
    </dependency>