28

I have a new springboot application I am attempting to get started.

The error I receive is

org.springframework.context.ApplicationContextException: Unable to start reactive web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ReactiveWebApplicationContext due to missing ReactiveWebServerFactory bean.
    at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.onRefresh(ReactiveWebServerApplicationContext.java:76) ~[spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]

src/main/java/bubbleshadow/RootController.java

package bubbleshadow;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@RestController
public class RootController {
  public RootController() {

  }

  @GetMapping("/")
  public Mono<HttpStatus> returnOk() {
    return Mono.just(HttpStatus.OK);
  }
}

src/test/java/test/bubbleshadow/RootControllerTest.java

package test.bubbleshadow;
import bubbleshadow.RootController;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
// import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes=RootController.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureWebTestClient
public class RootControllerTest {
  @Autowired
  WebTestClient webTestClient;

  @Test
  public void baseRouteShouldReturnStatusOK() {
    webTestClient.head().uri("/").exchange().expectStatus().isOk();
  }
}
Daniel Lynch
  • 313
  • 1
  • 4
  • 8

9 Answers9

16

Your configuration is not sufficient for reactive tests.

The reactive WebTestClient as well as ReactiveWebApplicationContext need reactive server in the application context. Add annotation @EnableAutoConfiguration to your RootControllerTest and let Spring's do it for you.

The autoconfiguration searches your class path and after find reactive classes and reactive context then create ReactiveWebServerFactory bean.

vdou
  • 281
  • 3
  • 5
  • 2
    I'm using Spring Boot version 2.2.5.RELEASE, and I also had to add the classes explicitly to the `@SpringBootTest` annotation (even though they were annotated with `@Configuration` and `@Component` respectively): `@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {FooConfig.class, FooHandler.class})` – user2337270 Apr 28 '20 at 00:38
  • I guess maybe a `@ComponentScan` annotation with the appropriate packages might do the trick as well. – user2337270 Apr 28 '20 at 00:46
15

I assume you are using maven to get your dependencies.

I solved the problem by using:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
        <version>2.0.3.RELEASE</version>
    </dependency>

Instead of:

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webflux</artifactId>
        <version>5.0.7.RELEASE</version>
    </dependency>
François Dupire
  • 585
  • 3
  • 11
  • 32
11

For me, the error was being caused by a missing @SpringBootApplication annotation on the Spring class containing the main() method entry point which actually starts the Boot application. Using the following resolved the error:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
D. Spreuer
  • 47
  • 8
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
4

Likely a corrupt download. Try removing ~/.m2/repository.

Stephan
  • 4,395
  • 3
  • 26
  • 49
Aniket Kulkarni
  • 1,985
  • 2
  • 17
  • 22
4

You actually just need to change webEnvironment = WebEnvironment.RANDOM_PORT to webEnvironment = WebEnvironment.MOCK in your @SpringBootTest annotation.

petronius
  • 451
  • 3
  • 11
1

@vdou's answer helped me to resolve my issue.

In addition to adding @EnableAutoConfiguration, I also had to manually add the spring application type:

spring:
  main:
    web-application-type: reactive

There is obviously something in my dependencies that is causing Spring not to be able to discover the type.

I hope this helps somebody...

apoplexy
  • 323
  • 2
  • 9
0

If you are using Kotlin, check if in your Application class that contains the main method, doesnt have this:

runApplication<Application>{
    webApplicationType = WebApplicationType.REACTIVE
}

Then change the "REACTIVE" to "SERVELET", will work like a charm.

0

If None of the above solutions work, try adding

@ContextConfiguration(loader = AnnotationConfigContextLoader.class)

It may help you

import org.springframework.test.context.support.AnnotationConfigContextLoader;
Javier
  • 12,100
  • 5
  • 46
  • 57
0

Yet another reason this can occur is if you're importing in a configuration class for your test that is not marked with @TestConfiguration annotation

MotiNK
  • 421
  • 2
  • 12