After reading release notes for Spring Framework 5.3 and the Reference Documentation I wanted to use WebTestClient in a Spring MVC application, but it fails with:
Injection of autowired dependencies failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/web/reactive/function/client/ExchangeFunction
Caused by: java.lang.NoClassDefFoundError: org/springframework/web/reactive/function/client/ExchangeFunction
at org.springframework.test.web.reactive.server.DefaultWebTestClientBuilder.build(DefaultWebTestClientBuilder.java:268)
at com.example.mvcwebtestclient.GreetingControllerTest.create(GreetingControllerTest.java:23)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Reproducing
build.gradle
dependencies {
implementation(platform("org.springframework.boot:spring-boot-dependencies:2.4.1"))
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb-reactive'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
}
GreetingController.java
@RestController
@RequestMapping("/greetings")
public class GreetingController {
@GetMapping
public Flux<String> findAll() {
return Flux.just("Hello", "world!");
}
}
GreetingControllerTest.java
@SpringBootTest
class GreetingControllerTest {
private WebTestClient client;
@Autowired
public void create(WebApplicationContext context) {
client = MockMvcWebTestClient.bindToApplicationContext(context)
.configureClient()
.build();
}
@Test
public void findsAll() {
client.get().uri("/greetings")
.exchange()
.expectStatus().isOk();
}
}
Workaround
Add webflux dependency:
implementation 'org.springframework.boot:spring-boot-starter-webflux'
I think it's a bug in code or at least a bug in documentation. The documentation does not mention in any place that you need WebFlux to test your MVC applications. This is an idea that looks absurd at first sight, so if it is really the case, it should be explicitly explained that you really need to do it.
Comment From: snicoll
WebTestClient
is a test wrapper around WebClient
. The very first link of the section you've referenced points to the WebClient
section that's part of Spring Webflux. I've transferred your issue to Spring Framework to determine if the doc could be more explicit about this.
Comment From: wagnerluis1982
Rather than only improving documentation, it would be much better if Spring could show a better message to the user.
Something in the lines of
Injection ... failed; you probably wanted to declare webflux dependencies in your pom.xml or build.gradle
Caused by: java.lang.NoClassDefFoundError: org/springframework/web/reactive/function/client/ExchangeFunction
at ...