Problem
I'm trying to run a simple spring boot test and I'm getting errors that suggest it can't MockMvc at runtime. Documentation suggests I'm using the correct annotations and I created my pom.xml using start.spring.io. Not sure why its having issues.
Error:
No qualifying bean of type 'org.springframework.test.web.servlet.MockMvc'
TestCode
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MyWebApplicationTests {
@Autowired
MockMvc mockMvc;
@Test
public void Can_Do_Something() throws Exception {
mockMvc.perform(get("/hello-world")).andDo(print()).andExpect(status().isOk())
.andExpect(content().string(containsString("Hello World")));
}
}
Documentation:
I was using this doc as a reference -> https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-testing-with-mock-environment
POM.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mywebapp</groupId>
<artifactId>webapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>my-webapp</name>
<description>Backend application</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.M1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>10</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
You need to use WebTestClient instead.
Typically @WebFluxTest is used in combination with @MockBean or @Import to create any collaborators required by your @Controller beans.
Interface WebTestClient. public interface WebTestClient. Client for testing web servers that uses WebClient internally to perform requests while also providing a fluent API to verify responses. This client can connect to any server over HTTP, or to a WebFlux application via mock request and response objects.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With