【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!"));
    }

}
相关推荐
追逐时光者1 小时前
推荐 12 款开源美观、简单易用的 WPF UI 控件库,让 WPF 应用界面焕然一新!
后端·.net
Jagger_1 小时前
敏捷开发流程-精简版
前端·后端
苏打水com2 小时前
数据库进阶实战:从性能优化到分布式架构的核心突破
数据库·后端
西瓜er3 小时前
JAVA:Spring Boot 集成 FFmpeg 实现多媒体处理
java·spring boot·ffmpeg
间彧3 小时前
Spring Cloud Gateway与Kong或Nginx等API网关相比有哪些优劣势?
后端
间彧3 小时前
如何基于Spring Cloud Gateway实现灰度发布的具体配置示例?
后端
间彧3 小时前
在实际项目中如何设计一个高可用的Spring Cloud Gateway集群?
后端
间彧3 小时前
如何为Spring Cloud Gateway配置具体的负载均衡策略?
后端
间彧4 小时前
Spring Cloud Gateway详解与应用实战
后端
EnCi Zheng5 小时前
SpringBoot 配置文件完全指南-从入门到精通
java·spring boot·后端