Reputation: 63
I'm just in the process of migrating our application to Spring Boot 3. One of the major changes I have to make is to replace our Zuul proxy server with Spring Cloud Gateway. But this change seems to mess with our Spring Integration Test setup.
The basic setup looks as follows:
This is a simplified version of the pom.xml of our project:
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>2022.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
</project>
Since we still use Spring MVC, I had to set the following property in the application.properties to get my application to start with Spring Cloud Gateway:
spring.main.web-application-type=reactive
Failing to set that properties lead to the following error during startup:
***************************
APPLICATION FAILED TO START
***************************
Description:
Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway.
Action:
Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency.
Process finished with exit code 1
After setting the property, my Spring Boot application starts and the proxy is working as well. However, now I have the problem that my existing Spring integration tests are not working anymore. It seems that setting the property spring.main.web-application-type to reactive prevents Spring from injecting the WebApplicationContext. My test setup is rather simple:
@SpringBootTest(classes = MainApplication.class, webEnvironment = DEFINED_PORT)
public class HealthControllerTest {
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
@BeforeEach
public void setup() {
mockMvc = MockMvcBuilders
.webAppContextSetup(this.context)
.build();
}
@Test
public void test() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.get(PATH)).
andExpect(MockMvcResultMatchers.status().isOk());
}
}
The test worked fine with Spring Boot 2, but now I get the following exception:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.web.context.WebApplicationContext' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1812)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1371)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:709)
... 76 more
As soon as I remove the Spring Cloud Gateway dependency and the spring.main.web-application-type property the dependency can be resolved and the test runs successfully.
Do you have a setup running with Spring Boot 3, Spring MVC and Spring Cloud Gateway and have an idea how to solve that issue?
Upvotes: 0
Views: 2835
Reputation: 63
Managed to get it up and running thanks to Andy Wilkinson. Switching to webtestclient worked for me. Test looks now just like this:
@SpringBootTest(classes = MainApplication.class, webEnvironment = DEFINED_PORT)
public class HealthControllerTest {
@Autowired
private WebTestClient webTestClient;
@Test
public void health_shouldReturnHttp200() { this.webTestClient.get().uri(PATH).accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk();
}
}
In order for this to run, also had to add spring-boot-starter-webflux as a dependency to my pom.xml.
Upvotes: 0