如何为含多参数(布尔参数)的GET API编写JUnit测试用例?
如何为带布尔参数的GET API编写JUnit测试用例?
针对你这个带有可选参数的GET API,咱们得把所有代码分支都覆盖到才能保证测试的完整性。这里我会用Spring Boot的@WebMvcTest来做Controller层的单元测试,同时Mock掉brandService,这样就不用依赖真实的数据库或业务逻辑啦。
测试思路
你的API里有这些关键分支需要覆盖:
- 默认参数场景(start、limit、show_rejected都不传)
- show_rejected为true/false的两种业务逻辑
- limit在合法范围(1-250)和非法范围(<1或>250)的情况
- 有数据返回和无数据返回的场景
- 业务层抛出异常的异常处理场景
完整测试代码示例
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import java.util.ArrayList; import java.util.List; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; // 替换成你的Controller实际类名 @WebMvcTest(BrandController.class) public class BrandControllerTest { @Autowired private MockMvc mockMvc; @MockBean private BrandService brandService; // Mock业务层,避免依赖真实实现 // 测试1:所有参数都不传,使用默认值(start=0, limit=50, show_rejected=false) @Test public void listBrands_withDefaultParams_returnsActiveBrands() throws Exception { // 模拟业务层返回分页数据 Page<Brand> mockPage = new PageImpl<>(List.of(new Brand())); when(brandService.findAllActiveBrands(0, 50)).thenReturn(mockPage); mockMvc.perform(get("/api/brand/multi-get") .contentType(MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().isOk()) .andExpect(jsonPath("$.code").value(ErrorCode.error_0)) .andExpect(jsonPath("$.message").value("Brand list")) .andExpect(jsonPath("$.data").isNotEmpty()); } // 测试2:show_rejected=true,返回所有品牌(包括已拒绝的) @Test public void listBrands_showRejectedTrue_returnsAllBrands() throws Exception { List<Brand> mockBrands = List.of(new Brand(), new Brand()); when(brandService.findAllBrands(0, 50)).thenReturn(mockBrands); mockMvc.perform(get("/api/brand/multi-get") .param("show_rejected", "true") .contentType(MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().isOk()) .andExpect(jsonPath("$.code").value(ErrorCode.error_0)) .andExpect(jsonPath("$.data.length()").value(2)); } // 测试3:show_rejected=true但无数据返回 @Test public void listBrands_showRejectedTrue_noData_returnsEmptyList() throws Exception { when(brandService.findAllBrands(0, 50)).thenReturn(new ArrayList<>()); mockMvc.perform(get("/api/brand/multi-get") .param("show_rejected", "true") .contentType(MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().isOk()) .andExpect(jsonPath("$.data").isEmpty()); } // 测试4:limit小于1,返回错误码1104 @Test public void listBrands_limitLessThan1_returnsError1104() throws Exception { mockMvc.perform(get("/api/brand/multi-get") .param("limit", "0") .contentType(MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().isOk()) .andExpect(jsonPath("$.code").value(ErrorCode.error_1104)) .andExpect(jsonPath("$.message").value(ErrorCode.error_msg1104)); } // 测试5:limit大于250,返回错误码1104 @Test public void listBrands_limitGreaterThan250_returnsError1104() throws Exception { mockMvc.perform(get("/api/brand/multi-get") .param("limit", "251") .contentType(MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().isOk()) .andExpect(jsonPath("$.code").value(ErrorCode.error_1104)); } // 测试6:自定义start和limit,show_rejected=false @Test public void listBrands_customStartAndLimit_returnsActiveBrands() throws Exception { Page<Brand> mockPage = new PageImpl<>(List.of(new Brand())); when(brandService.findAllActiveBrands(10, 100)).thenReturn(mockPage); mockMvc.perform(get("/api/brand/multi-get") .param("start", "10") .param("limit", "100") .contentType(MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().isOk()) .andExpect(jsonPath("$.data").isNotEmpty()); } // 测试7:业务层抛出异常,验证异常处理逻辑 @Test public void listBrands_serviceThrowsException_returnsDefaultResponse() throws Exception { when(brandService.findAllActiveBrands(0, 50)).thenThrow(new RuntimeException("Test exception")); mockMvc.perform(get("/api/brand/multi-get") .contentType(MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().isOk()) // 你的代码里异常时会返回空的responseDTO,这里根据实际返回值调整断言 .andExpect(jsonPath("$.code").isEmpty()); } }
一些注意点
- 记得把代码里的
BrandController、BrandService、Brand替换成你实际的类名 @MockBean会帮你创建一个Mock的业务层实例,你可以用when()方法来指定它的返回值或抛出异常- 因为你的API声明了
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,所以测试时要设置contentType为对应的类型 - 每个测试用例都对应了一个代码分支,这样能保证你的API逻辑都被验证到
内容的提问来源于stack exchange,提问作者Chandana S
相关产品推荐
相关产品推荐

