这个项目是基于若依的多模块项目,用的SpringBootTest测试方法,这个测试方法会通过web的方式与其它模块中的controller发送数据,发现发送数据时找不到自己所在端口的项目。
@SpringBootTest 注解的本质确实是用于测试 SpringBoot 应用的代码逻辑,并提供一个模拟的应用环境。然而,这种模拟的环境的范围和行为是可以配置的。@SpringBootTest 不仅可以隔离测试环境,还能根据配置,启动一个几乎等同于生产环境的应用上下文。
当你使用 @SpringBootTest 时,Spring Boot 会加载整个应用的上下文(ApplicationContext),这包括了所有的配置、服务、控制器(Controller)等。关键在于 webEnvironment 属性的设置:
默认情况下(即 webEnvironment = WebEnvironment.MOCK),Spring Boot 使用模拟的Web环境。这种情况下,实际的网络服务不会启动,但所有的 Spring Beans 都会被加载和注册。
如果设置为 WebEnvironment.RANDOM_PORT 或 WebEnvironment.DEFINED_PORT,则会启动一个嵌入式的Web服务器(如 Tomcat),在指定的端口上侦听请求。这意味着实际的网络服务被启动,你的应用将表现得就像在生产环境中运行一样,所有模块中的 Controller 都能接收和响应网络请求。
因此,如果你发现在使用 @SpringBootTest 时无法访问某些 Controller,可能是因为你没有正确配置 webEnvironment,或者测试时的应用配置与实际运行的配置有所不同。确保你的测试配置正确引用了需要测试的所有模块和配置文件。
这是因为 @SpringBootTest 本质上是为了可以在隔离的环境中测试代码逻辑,而不是完全模拟整个SpringBoot应用的行为。
把StringBoot的main类先启动再启动测试方法就能访问到了。
Spring Boot测试中,webEnvironment 属性的主要作用是定义测试运行时Spring Boot应用如何处理Web环境。这个属性可以配置在 @SpringBootTest 注解中,它决定了是否启动一个嵌入式Web服务器以及如何启动这个服务器。以下是该属性的四种可能配置:
1. WebEnvironment.MOCK
默认配置,使用模拟的Servlet环境。这个设置不会启动嵌入式服务器,但会完全创建Spring应用上下文。适用于测试Spring MVC的Controller,通常与 @AutoConfigureMockMvc 或 @WebMvcTest 结合使用来模拟HTTP请求。
2. WebEnvironment.RANDOM_PORT
使用这个配置,Spring Boot会启动一个嵌入式的Web服务器,并在一个随机选择的可用端口上运行。这对于集成测试很有用,特别是当测试的交互需要实际的网络环境时。
3. WebEnvironment.DEFINED_PORT
与 RANDOM_PORT 类似,但是会使用应用配置文件中定义的特定端口(如 application.properties 中的 server.port)。这样的配置适用于需要测试与特定端口交互的集成测试。
4. WebEnvironment.NONE
不提供任何Web环境支持。这个设置也不会创建任何与Web相关的Spring Bean,主要用于纯后端逻辑的测试,不涉及Web层的任何部分。
使用application.yml中特定的端口进行启动测试。
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class ApplicationPortTests {
@Value("${local.server.port}")
private int port; // 使用@Value注解注入端口值
@Autowired
private TestRestTemplate restTemplate;
@Test
public void exampleTest() {
// 构建URL使用定义的端口
String url = "http://localhost:" + port + "/someEndpoint";
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
}
}