【Springboot】单元测试Junit5应用

JUnit 5是一个功能强大的测试框架,常用于编写和执行这些单元测试。以下是一些JUnit 5中的常用注解、断言、前置条件、嵌套测试和参数化测试的例子:

1.环境启动

@SpringBootTest 注解:

classes = SmartApplication.class:这个属性指定了一个或多个Spring Boot应用程序的启动类(入口点)。在测试中使用启动类可以让Spring Boot应用程序的上下文被加载,以便进行测试。

webEnvironment属性:

  • NONE: 不启动任何Web相关的环境,通常用于不需要Web环境的测试。
  • RANDOM_PORT: 随机分配一个端口来启动Web环境。
  • ANY: 使用第一个可用端口来启动Web环境。
  • MOCK: 使用MockMvc来模拟Web环境,而不用启动真实的Web服务器。
  • DEFINED_PORT: 使用在@LocalServerPort或@Value注解中定义的端口来启动Web环境。使用配置文件中定义好的端口
java 复制代码
@SpringBootTest(classes = SmartApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
class JunitApplicationTests {
	
	@Autowired
	TestService testService;

	@Test
	void contextLoads() {
		System.err.println("测试启动");
		System.out.println(testService.test());
	}

}

2. 常用注解

  • @Test:用于标记一个方法作为测试方法。
  • @BeforeEach:在每个测试方法之前执行一次。
  • @AfterEach:在每个测试方法之后执行一次。
  • @BeforeAll:在所有测试方法之前执行一次。
  • @AfterAll:在所有测试方法之后执行一次。
java 复制代码
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;

public class MyServiceTest {

    private MyService service;

    @BeforeAll
    public static void setup() {
        // 在所有测试之前执行的代码
    }

    @BeforeEach
    public void setupEachTest() {
        // 在每个测试之前执行的代码
        service = new MyService();
    }

    @AfterEach
    public void teardown() {
        // 在每个测试之后执行的代码
    }

    @AfterAll
    public static void teardown() {
        // 在所有测试之后执行的代码
    }

    @Test
    public void myTestMethod() {
        // 测试逻辑
    }
}

3.模拟发送HTTP请求

断言

  • Assertions.assertEquals(expected, actual):断言期望值与实际值相等。
  • Assertions.assertNotEquals(unexpected, actual):断言期望值与实际值不等。
  • Assertions.assertNull(object):断言对象为null。
  • Assertions.assertNotNull(object):断言对象不为null。
  • Assertions.assertTrue(condition):断言条件为true。
  • Assertions.assertFalse(condition):断言条件为false。

使用RestTemplate发送请求

java 复制代码
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = YourApplication.class)
public class YourControllerTest {

    @Autowired
    private RestTemplate restTemplate;

    @Test
    public void should_handle_request_correctly() {
        // 模拟请求
        String url = "http://example.com/api";
        HttpEntity<String> request = new HttpEntity<>("some request body", headers);
        
        // 发送请求
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
        
        // 断言
        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertEquals("expected response body", response.getBody());
    }
}

使用Mock发送请求

java 复制代码
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

import java.util.HashMap;
import java.util.Map;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import com.example.yourproject.controller.YourController;

@ExtendWith(MockitoExtension.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class YourControllerTest {

    @Mock
    private YourController yourController;

    private MockMvc mockMvc;

    @BeforeEach
    public void setUp() {
        mockMvc = MockMvcBuilders.standaloneSetup(yourController).build();
    }

    @Test
    public void testYourController() throws Exception {
        // 准备请求参数
        Map<String, String> requestParams = new HashMap<>();
        requestParams.put("param1", "value1");
        requestParams.put("param2", "value2");

        // 设置模拟的响应
        String expectedResponse = "{\"message\":\"Hello World!\"}";
        when(yourController.yourMethod(requestParams)).thenReturn(expectedResponse);

        // 发送请求并验证结果
        mockMvc.perform(MockMvcRequestBuilders.post("/your-endpoint")
                .contentType(MediaType.APPLICATION_JSON)
                .content(JSON.toJSONString(requestParams)))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_VALUE))
                .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("Hello World!"));
    }

}
相关推荐
老华带你飞13 分钟前
出行旅游安排|基于springboot出行旅游安排系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·spring·旅游
舒一笑22 分钟前
在低配云服务器上实现自动化部署:Drone CI + Gitee Webhook 的轻量级实践
前端·后端·程序员
李广坤24 分钟前
Rust基本使用
后端·rust
我是你们的明哥28 分钟前
Java优先级队列(PriorityQueue)详解:原理、用法与实战示例
后端·算法
m0_7400437338 分钟前
SpringBoot快速入门01- Spring 的 IOC/DI、AOP,
spring boot·后端·spring
JIngJaneIL1 小时前
基于Java饮食营养管理信息平台系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot
IT_陈寒1 小时前
Java 21新特性实战:这5个改进让我的代码效率提升40%
前端·人工智能·后端
程序员爱钓鱼1 小时前
Mac必备技巧:使用 tree命令快速查看目录结构
后端·go·trae
老华带你飞1 小时前
垃圾分类|基于springboot 垃圾分类系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·spring
chenyuhao20241 小时前
Linux系统编程:Ext文件系统
linux·运维·服务器·开发语言·网络·c++·后端