精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

八種測(cè)試方法,讓 Spring Boot 接口穩(wěn)定性提升 200%

開(kāi)發(fā) 架構(gòu)
進(jìn)行系統(tǒng)化的 Controller 接口測(cè)試至關(guān)重要。它不僅能驗(yàn)證 API 的正確性、保障數(shù)據(jù)交互的準(zhǔn)確性,還能提前暴露集成缺陷,確保在各種邊界和異常場(chǎng)景下系統(tǒng)行為符合預(yù)期,是提升軟件質(zhì)量、支撐持續(xù)交付的關(guān)鍵環(huán)節(jié)。

環(huán)境:SpringBoot3.4.2

1. 簡(jiǎn)介

在前后端分離架構(gòu)中,Controller 作為系統(tǒng)的 "門(mén)面",承擔(dān)著接收請(qǐng)求、處理參數(shù)、調(diào)用業(yè)務(wù)邏輯并返回響應(yīng)的核心職責(zé)。其接口的穩(wěn)定性直接關(guān)系到整個(gè)系統(tǒng)的可用性與用戶(hù)體驗(yàn)。

因此,進(jìn)行系統(tǒng)化的 Controller 接口測(cè)試至關(guān)重要。它不僅能驗(yàn)證 API 的正確性、保障數(shù)據(jù)交互的準(zhǔn)確性,還能提前暴露集成缺陷,確保在各種邊界和異常場(chǎng)景下系統(tǒng)行為符合預(yù)期,是提升軟件質(zhì)量、支撐持續(xù)交付的關(guān)鍵環(huán)節(jié)。

通常Controller層主要做如下的驗(yàn)證:

  • 請(qǐng)求映射
    驗(yàn)證 HTTP 方法(GET/POST 等)、路徑(/users/{id})是否正確映射到目標(biāo)方法。
  • 請(qǐng)求/響應(yīng)的序列化與反序列化
    確保 JSON 與 Java 對(duì)象之間的轉(zhuǎn)換(@RequestBody, @ResponseBody)準(zhǔn)確無(wú)誤。
  • 驗(yàn)證、異常處理與 HTTP 狀態(tài)碼
    測(cè)試數(shù)據(jù)校驗(yàn)(@Valid)、全局異常處理器(@ControllerAdvice)能否正確返回 400、404、500 等狀態(tài)碼。
  • 與服務(wù)層的集成
    驗(yàn)證 Controller 是否正確調(diào)用 Service 方法,參數(shù)傳遞無(wú)誤。可通過(guò) @MockBean 模擬依賴(lài),或連接真實(shí)服務(wù)進(jìn)行測(cè)試。

2.實(shí)戰(zhàn)案例

準(zhǔn)備環(huán)境

public record User(Long id, String name, Integer age) {
}
@Service
public class UserService {
  public User queryUser(Long id) {
    return new User(id, "Pack_xg", 33) ;
  }


  public List<User> queryUsers() {
    return List.of(new User(1L, "pack", 33)) ;
  }


  public User save(User user) {
    System.err.println("創(chuàng)建用戶(hù)...") ;
    return user ;
  }
}
// Controller接口
@RestController
@RequestMapping("/users")
public class UserController {
  private final UserService userService ;
  public UserController(UserService userService) {
    this.userService = userService ;
  }
  @GetMapping("/{id}")
  public User queryUser(@PathVariable Long id) {
    return this.userService.queryUser(id);
  }


  @GetMapping("")
  public List<User> queryUsers() {
    return this.userService.queryUsers() ;
  }


  @PostMapping("")
  @ResponseStatus(code = HttpStatus.CREATED)
  public User save(@RequestBody User user) {
    return user ;
  }
}

接下來(lái),我們將通過(guò)8種方法對(duì)上面的接口進(jìn)行不同場(chǎng)景下的測(cè)試。

2.1 使用 @WebMvcTest

目的

該方法通過(guò)模擬所有依賴(lài)項(xiàng)(如服務(wù)層、數(shù)據(jù)訪問(wèn)層),實(shí)現(xiàn)對(duì)控制器層的獨(dú)立隔離測(cè)試。

你可以驗(yàn)證以下關(guān)鍵點(diǎn):

  • ? URL 映射:例如,GET /users 是否正確調(diào)用了對(duì)應(yīng)的處理方法。
  • ? 請(qǐng)求/響應(yīng)處理:請(qǐng)求參數(shù)和請(qǐng)求體能否正確反序列化,響應(yīng)對(duì)象能否正確序列化為 JSON 或 XML。
  • ? HTTP 狀態(tài)碼與錯(cuò)誤響應(yīng):正常請(qǐng)求返回 200 OK,資源未找到返回 404 Not Found,參數(shù)校驗(yàn)失敗返回 400 Bad Request 等。
  • ? 與模擬服務(wù)的交互:控制器是否按預(yù)期調(diào)用了服務(wù)層方法,傳遞的參數(shù)是否正確,行為是否符合設(shè)計(jì)。

核心注解&類(lèi)說(shuō)明:

  • @WebMvcTest(YourController.class) :Spring Boot 僅加載 Web 層(如控制器、攔截器、消息轉(zhuǎn)換器等),不會(huì)啟動(dòng)完整的應(yīng)用上下文,從而實(shí)現(xiàn)快速、專(zhuān)注的測(cè)試。
  • MockMvc :用于模擬 HTTP 請(qǐng)求(如 GET、POST),并驗(yàn)證響應(yīng)(如狀態(tài)碼、響應(yīng)體內(nèi)容),無(wú)需啟動(dòng)真實(shí)服務(wù)器。
  • @MockBean: 將應(yīng)用上下文中真實(shí)的依賴(lài)服務(wù)(例如 UserService)替換為 Mockito 模擬對(duì)象,從而隔離外部依賴(lài),精準(zhǔn)控制和驗(yàn)證服務(wù)調(diào)用行為。

測(cè)試用例:

@WebMvcTest(UserController.class)
public class UserControllerTest1 {
  // 用于模擬 HTTP 請(qǐng)求。
  @Resource
  private MockMvc mockMvc;
  // 被模擬的服務(wù)(真實(shí)的服務(wù)被忽略)。
  @MockitoBean
  private UserService userService;
  @Test
  public void testUsers() throws Exception {
    // 1.設(shè)置模擬行為
    when(userService.queryUsers()).thenReturn(List.of(new User(1L, "pack", 33))) ;
    // 2.模擬 HTTP GET 請(qǐng)求到 /users 并驗(yàn)證響應(yīng)
    mockMvc.perform(get("/users"))
      .andExpect(status().isOk())
      .andExpect(jsonPath("$[0].name").value("pack"));
  }
  @Test
  public void testUser() throws Exception {
    when(userService.queryUser(1L))
      .thenThrow(new UserNotFoundException());
    mockMvc.perform(get("/users/1"))
      .andExpect(status().isNotFound());
  }
}

? 優(yōu)點(diǎn)

  • ? 執(zhí)行速度快:無(wú)需連接數(shù)據(jù)庫(kù)或進(jìn)行真實(shí)網(wǎng)絡(luò)調(diào)用,測(cè)試運(yùn)行迅速。
  • ? 隔離控制器邏輯:排除服務(wù)層、數(shù)據(jù)層等外部干擾,精準(zhǔn)驗(yàn)證控制器自身行為。
  • ? 適合驗(yàn)證請(qǐng)求/響應(yīng)格式:可有效測(cè)試 URL 映射、參數(shù)綁定、JSON 序列化、狀態(tài)碼及錯(cuò)誤響應(yīng)結(jié)構(gòu)。

? 缺點(diǎn)

  • ? 不測(cè)試真實(shí)的服務(wù)/數(shù)據(jù)層集成:由于依賴(lài)被模擬,無(wú)法發(fā)現(xiàn)真實(shí)調(diào)用中的集成問(wèn)題。
  • ? 對(duì) Spring 上下文的驗(yàn)證有限:某些全局配置(如安全過(guò)濾器鏈、自定義攔截器)的行為可能與完整應(yīng)用環(huán)境存在差異。

何時(shí)使用 @WebMvcTest?

  • 當(dāng)你需要快速、專(zhuān)注地測(cè)試控制器邏輯時(shí)。
  • 當(dāng)你的重點(diǎn)是驗(yàn)證 HTTP 響應(yīng)格式、狀態(tài)碼和異常處理機(jī)制時(shí)。
  • 當(dāng)你不需要啟動(dòng)完整的 Spring 上下文(如數(shù)據(jù)庫(kù)、消息隊(duì)列、完整安全配置)時(shí)。

2.2 @SpringBootTest + MockMvc 進(jìn)行全面集成測(cè)試

目的

這種方法可測(cè)試整個(gè)應(yīng)用堆棧,包括:

  • ? 控制器(Controllers):HTTP 請(qǐng)求的接收、路由、參數(shù)綁定與響應(yīng)處理。
  • ? 服務(wù)層(Services):核心業(yè)務(wù)邏輯的正確執(zhí)行。
  • ? 數(shù)據(jù)訪問(wèn)層(Repositories):與數(shù)據(jù)庫(kù)的實(shí)際交互,包括 CRUD 操作和事務(wù)管理。
  • ? 配置(Configuration):安全策略(如 Spring Security)、過(guò)濾器、攔截器、消息轉(zhuǎn)換器、序列化設(shè)置等全局配置是否按預(yù)期生效。

與 @WebMvcTest 不同,此方法不會(huì)模擬服務(wù)或數(shù)據(jù)訪問(wèn)層(除非顯式指定)。相反,它使用:

  • 一個(gè)真實(shí)的(或內(nèi)存中的)數(shù)據(jù)庫(kù)(例如,測(cè)試時(shí)使用 H2)
  • 實(shí)際的服務(wù)層(除非需要,否則不進(jìn)行模擬)
  • 完整的 Spring 上下文(與生產(chǎn)環(huán)境類(lèi)似)

核心注解 & 類(lèi)

  • @SpringBootTest:?jiǎn)?dòng)完整的 Spring 應(yīng)用程序上下文。
  • @AutoConfigureMockMvc: 啟用 MockMvc 以進(jìn)行 HTTP 測(cè)試(無(wú)需啟動(dòng)真實(shí)服務(wù)器)。

測(cè)試用例:

@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTest2 {
  // 用于模擬 HTTP 請(qǐng)求。
  @Resource
  private MockMvc mockMvc;
  // 被模擬的服務(wù)(真實(shí)的服務(wù)被忽略)。
  @MockitoBean
  private UserService userService;
  @Test
  public void testSave() throws Exception {
    String jsonBody = """
        {"id": 2, "name": "admin", "age": 33}
        """;
    mockMvc.perform(post("/users")
        .contentType(MediaType.APPLICATION_JSON)
        .content(jsonBody))
        // 檢查狀態(tài)碼是否201
        .andExpect(status().isCreated())
        // 檢查返回值的name屬性是否是admin
        .andExpect(jsonPath("$.name").value("admin"));
  }
}

? 優(yōu)點(diǎn)

  • ? 測(cè)試完整流程(控制器 → 服務(wù) → 數(shù)據(jù)訪問(wèn)層 → 數(shù)據(jù)庫(kù))
  • ? 發(fā)現(xiàn)集成問(wèn)題(如 JSON 解析錯(cuò)誤、數(shù)據(jù)庫(kù)約束沖突)
  • ? 更貼近真實(shí)運(yùn)行行為(相比模擬測(cè)試)

? 缺點(diǎn)

  • ? 速度較慢(需啟動(dòng)完整 Spring 上下文和數(shù)據(jù)庫(kù))
  • ? 需要配置測(cè)試數(shù)據(jù)庫(kù)(如 H2、Testcontainers 等)
  • ? 難以定位問(wèn)題(失敗可能來(lái)自任意一層)

何時(shí)使用 @SpringBootTest?

  • 當(dāng)你需要進(jìn)行端到端測(cè)試(API 到數(shù)據(jù)庫(kù))時(shí)。
  • 當(dāng)模擬不足以滿足需求時(shí)(例如測(cè)試事務(wù)、安全配置)。
  • 當(dāng)需要驗(yàn)證真實(shí)數(shù)據(jù)庫(kù)約束(如唯一字段、外鍵關(guān)系)時(shí)。

2.3 使用 WebTestClient 進(jìn)行測(cè)試

WebTestClient 是 MockMvc 和 TestRestTemplate 的現(xiàn)代、靈活替代方案,支持:

  • ? 響應(yīng)式應(yīng)用(Spring WebFlux)
  • ? 傳統(tǒng)的阻塞式控制器(Spring MVC)
  • ? 流暢的鏈?zhǔn)?API,便于進(jìn)行請(qǐng)求/響應(yīng)驗(yàn)證

它可以測(cè)試:

  • HTTP 端點(diǎn)(REST、GraphQL 等)
  • 響應(yīng)狀態(tài)碼、響應(yīng)頭和響應(yīng)體
  • 錯(cuò)誤處理和流式響應(yīng)

測(cè)試用例:

// 使用下面2個(gè)注解都可以
// @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@WebFluxTest(UserController.class) 
public class UserControllerTest3 {
  @Resource
  private WebTestClient webTestClient;
  @MockitoBean
  private UserService userService;
  @Test
  public void testQueryUsers() throws Exception {
    when(userService.queryUsers()).thenReturn(List.of(new User(1L, "pack", 33))) ;
    webTestClient.get().uri("/users")  
      .exchange() 
      .expectStatus().isOk()  
      .expectBody()  
      .jsonPath("$[0].name").isEqualTo("pack");
  }
}

? 優(yōu)點(diǎn)

  • ? 統(tǒng)一支持 MVC 與 WebFlux 應(yīng)用
  • ? 比 MockMvc 更易讀(流暢式 API 風(fēng)格)
  • ? 支持流式響應(yīng)測(cè)試(如 SSE、WebSocket)
  • ? 既可用于模擬環(huán)境,也可連接真實(shí)服務(wù)器

? 缺點(diǎn)

  • ? 相對(duì)較新,部分團(tuán)隊(duì)仍偏好 MockMvc
  • ? 對(duì)于純 MVC 應(yīng)用,相比 MockMvc 略缺乏細(xì)粒度控制

何時(shí)使用 WebTestClient?

  • 若你的應(yīng)用基于響應(yīng)式(WebFlux)→ 首選方案。
  • 若你希望使用統(tǒng)一工具測(cè)試 MVC 和 WebFlux 控制器。
  • 若你偏好流暢、現(xiàn)代的斷言風(fēng)格,而非 MockMvc 的 DSL 風(fēng)格。

2.4 使用 TestRestTemplate 進(jìn)行測(cè)試

目的

TestRestTemplate 是一個(gè)真實(shí)的 HTTP 客戶(hù)端,向正在運(yùn)行的 Spring Boot 應(yīng)用程序發(fā)送實(shí)際的 HTTP 請(qǐng)求。與模擬請(qǐng)求的 MockMvc 不同,它:

  • ? 發(fā)起真實(shí)的網(wǎng)絡(luò)調(diào)用(如同瀏覽器或 Postman)
  • ? 測(cè)試完整的服務(wù)器行為(包括過(guò)濾器、安全機(jī)制和錯(cuò)誤處理)
  • ? 可用于測(cè)試任何 REST 端點(diǎn)(不僅限于 Spring 控制器)

最適合用于:

  • 端到端的 API 測(cè)試
  • 認(rèn)證功能測(cè)試(如 OAuth、JWT)
  • 驗(yàn)證負(fù)載均衡器與代理行為

測(cè)試用例:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class UserControllerTest4 {
  @Resource
  private TestRestTemplate restTemplate;
  @Test
  public void testQueryUsers() throws Exception {
    ResponseEntity<User[]> response = restTemplate.getForEntity("/users", User[].class);  
    assertEquals(HttpStatus.OK, response.getStatusCode());  
    assertEquals("pack", response.getBody()[0].name());  
  }
}

? 優(yōu)點(diǎn)

  • ? 測(cè)試真實(shí)的 HTTP 行為(請(qǐng)求頭、Cookie、SSL 等)
  • ? 可用于測(cè)試外部 API(不僅限于 Spring 控制器)
  • ? 適合與其他服務(wù)進(jìn)行集成測(cè)試

? 缺點(diǎn)

  • ? 速度較慢(需啟動(dòng)完整服務(wù)器并進(jìn)行網(wǎng)絡(luò)調(diào)用)
  • ? 相比 MockMvc 控制力較弱(無(wú)法直接模擬內(nèi)部行為)
  • ? 更難調(diào)試(失敗可能源于網(wǎng)絡(luò)問(wèn)題而非應(yīng)用邏輯)

何時(shí)使用 TestRestTemplate?

  • 測(cè)試 API 網(wǎng)關(guān)或代理
  • 驗(yàn)證 HTTPS、CORS 或安全過(guò)濾器的行為
  • 需要與外部服務(wù)交互的端到端測(cè)試

2.5 獨(dú)立模式 MockMvc(無(wú) Spring 上下文)

這種方式允許你在完全隔離的環(huán)境下測(cè)試單個(gè)控制器,無(wú)需:

  • 加載 Spring 上下文
  • 執(zhí)行自動(dòng)配置
  • 觸發(fā)過(guò)濾器、攔截器或 AOP 通知

取而代之的是:

  • ? 手動(dòng)創(chuàng)建控制器(并注入模擬的依賴(lài))
  • ? 使用 MockMvcBuilders.standaloneSetup()(無(wú)需 @SpringBootTest)
  • ? 獲得極快的測(cè)試執(zhí)行速度(非常適合 TDD 快速反饋)

測(cè)試用例:

public class UserControllerTest5 {
  private MockMvc mockMvc;
  private UserService userService = mock(UserService.class);
  @BeforeEach
  public void setup() {
    // 1.手動(dòng)創(chuàng)建Controller接口
    UserController controller = new UserController(userService);
    // 2.不使用Spring構(gòu)建MockMvc
    mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
  }
  @Test
  public void testQueryUsers() throws Exception {
    // 3.模擬測(cè)試行為
    when(userService.queryUsers()).thenReturn(List.of(new User(1L, "pack", 33))); 
    // 4.測(cè)試接口  
    mockMvc.perform(get("/users"))  
           .andExpect(status().isOk())  
           .andExpect(jsonPath("$[0].name").value("pack1"));  
  }
}

? 優(yōu)點(diǎn)

  • ? 極快執(zhí)行(無(wú) Spring 啟動(dòng)開(kāi)銷(xiāo))
  • ? 完全掌控依賴(lài)(無(wú)隱式 @Autowired 行為)
  • ? 非常適合單元測(cè)試純控制器邏輯

? 缺點(diǎn)

  • ? 不支持 Spring 功能(如 @Valid 數(shù)據(jù)驗(yàn)證、@ControllerAdvice 異常處理、安全注解等)
  • ? 需手動(dòng)配置(必須顯式注入所有依賴(lài))
  • ? 不夠真實(shí)(行為可能與生產(chǎn)環(huán)境存在差異)

何時(shí)使用 Standalone MockMvc?

  • 需要完全隔離地測(cè)試控制器內(nèi)部邏輯時(shí)
  • 進(jìn)行超高速單元測(cè)試,追求極致的 TDD 快速反饋
  • 希望徹底避免 Spring 上下文啟動(dòng)開(kāi)銷(xiāo)的場(chǎng)景

2.6 REST Assured — 流暢 API 測(cè)試

目的

REST Assured 是一個(gè)用于測(cè)試 REST API 的 Java 領(lǐng)域特定語(yǔ)言(DSL),采用流暢的、行為驅(qū)動(dòng)(BDD)風(fēng)格編寫(xiě)測(cè)試。它:

  • ? 使測(cè)試代碼更具可讀性(類(lèi)似自然語(yǔ)言)
  • ? 支持復(fù)雜驗(yàn)證(JSON Path、XML、Schema 等)
  • ? 可與任何 HTTP 服務(wù)器(Spring Boot、Node.js 等)配合使用

最適合用于:

  • API 契約測(cè)試:驗(yàn)證接口的請(qǐng)求/響應(yīng)格式是否符合約定。
  • 與外部服務(wù)的集成測(cè)試:測(cè)試應(yīng)用與第三方 API 的交互。
  • 采用 BDD(Given-When-Then)實(shí)踐的團(tuán)隊(duì):統(tǒng)一測(cè)試語(yǔ)言,提升協(xié)作效率。

測(cè)試用例:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class UserControllerTest6 {
  // 注入隨機(jī)端口
  @LocalServerPort
  private int port;
  @Test
  public void testQueryUsers() {
    given().port(port) // 設(shè)置端口
        // 當(dāng):調(diào)用 GET /users
        .when().get("/users")
        // 那么:驗(yàn)證響應(yīng)
        .then().statusCode(200) // HTTP 200 OK
        .body("[0].name", equalTo("pack")) // 檢查 JSON
        .body("size()", greaterThan(1)); // 其他斷言
  }
}

注意,你需要引入如下依賴(lài):

<dependency>
  <groupId>io.rest-assured</groupId>
  <artifactId>rest-assured</artifactId>
  <scope>test</scope>
</dependency>

? 優(yōu)點(diǎn)

  • ? 語(yǔ)法可讀性強(qiáng),采用 BDD 風(fēng)格(清晰的 given-when-then 結(jié)構(gòu))
  • ? 斷言功能強(qiáng)大(支持 JSON Path、Hamcrest 匹配器)
  • ? 支持多種認(rèn)證方式(OAuth2、Basic Auth 等
  • ? 可用于測(cè)試任何 REST API(不僅限于 Spring Boot 應(yīng)用)

? 缺點(diǎn)

  • ? 需要引入額外依賴(lài)(增加 pom.xml 或 build.gradle 的體積)
  • ? 相比 MockMvc 稍慢(通常基于真實(shí) HTTP 調(diào)用)
  • ? 學(xué)習(xí)曲線較陡(DSL 語(yǔ)法有其獨(dú)特性)

何時(shí)使用 REST Assured?

  • 測(cè)試第三方或外部 API
  • 編寫(xiě)易于理解、可讀性高的集成測(cè)試
  • 需要驗(yàn)證復(fù)雜的 JSON/XML 響應(yīng)結(jié)構(gòu)時(shí)

2.7 測(cè)試 Controller Advice 與異常處理

目的

驗(yàn)證以下關(guān)鍵環(huán)節(jié):

  • ? 全局異常處理器(@ControllerAdvice)能否正確捕獲并處理異常
  • ? 自定義錯(cuò)誤響應(yīng)(JSON/XML 格式)是否符合 API 規(guī)范
  • ? 返回的 HTTP 狀態(tài)碼是否與錯(cuò)誤類(lèi)型匹配(如 404、400、500 等)

首先,準(zhǔn)備@ControllerAdvice全局異常處理

@RestControllerAdvice
public class UserControllerAdvice {
  @ExceptionHandler(UserNotFoundException.class)
  public ResponseEntity<?> error(UserNotFoundException e) {
    return ResponseEntity.status(404).body(Map.of("code", -1, "error", e.getMessage())) ;
  }
}
public class UserNotFoundException extends RuntimeException {
  public UserNotFoundException() {
    super();
  }
  public UserNotFoundException(String message) {
    super(message);
  }
  public UserNotFoundException(String message, Throwable cause) {
    super(message, cause);
  }
}

測(cè)試用例:

@WebMvcTest(UserController.class)
public class UserControllerTest7 {
  // 用于模擬 HTTP 請(qǐng)求。
  @Resource
  private MockMvc mockMvc;
  // 被模擬的服務(wù)
  @MockitoBean
  private UserService userService;
  @Test
  public void testUser() throws Exception {
    when(userService.queryUser(1L)).thenThrow(new UserNotFoundException("用戶(hù)不存在1"));
    mockMvc.perform(get("/users/1"))  
      .andExpect(status().isNotFound())
      .andExpect(jsonPath("$.error").value("用戶(hù)不存在"));
  }
}

最佳實(shí)踐

  • ? 結(jié)合測(cè)試模擬與真實(shí)異常場(chǎng)景:既測(cè)試手動(dòng)拋異常的路徑,也測(cè)試由框架觸發(fā)的異常(如參數(shù)校驗(yàn)失敗)
  • ? 驗(yàn)證錯(cuò)誤響應(yīng)結(jié)構(gòu):確保返回的錯(cuò)誤 JSON/XML 字段(如 code, message, timestamp)符合 API 文檔規(guī)范
  • ? 在測(cè)試中包含錯(cuò)誤日志輸出:使用 .andDo(print()) 打印請(qǐng)求/響應(yīng)詳情,便于調(diào)試失敗用例

2.8 使用 Mockito 進(jìn)行純單元測(cè)試

目的

該方法完全繞過(guò) HTTP 協(xié)議和 Spring 框架,僅專(zhuān)注于測(cè)試 Java 方法調(diào)用。適用于:

  • ? 隔離控制器邏輯(例如,調(diào)用服務(wù)前的請(qǐng)求參數(shù)處理與業(yè)務(wù)判斷)
  • ? 極致快速的單元測(cè)試(無(wú) Spring 上下文啟動(dòng)、無(wú) HTTP 開(kāi)銷(xiāo))
  • ? 驗(yàn)證與依賴(lài)組件的交互(如是否正確調(diào)用 UserService 及參數(shù)傳遞)

測(cè)試用例:

public class UserControllerTest8 {
  private UserService userService = mock(UserService.class);  
  private UserController userController = new UserController(userService);
  @Test
  public void testQueryUsers() throws Exception {
    when(userService.queryUsers()).thenReturn(List.of(new User(1L, "pack", 33)));


    List<User> users = userController.queryUsers() ;  
    assertEquals("pack", users.get(0).name());  
    verify(userService).queryUsers() ; 
  }
}

? 優(yōu)點(diǎn)

  • ? 速度最快(無(wú)任何框架開(kāi)銷(xiāo))
  • ? 對(duì)依賴(lài)完全可控(所有依賴(lài)均可模擬)
  • ? 適合測(cè)試控制器內(nèi)的復(fù)雜業(yè)務(wù)邏輯

? 缺點(diǎn)

  • ? 不測(cè)試 HTTP 映射(如 @GetMapping、@PostMapping 是否正確)
  • ? 忽略序列化/驗(yàn)證邏輯(無(wú) JSON 轉(zhuǎn)換、無(wú)參數(shù)綁定過(guò)程)
  • ? 無(wú)法覆蓋 Spring 特性(如 @Valid 校驗(yàn)、安全注解等)

何時(shí)使用純 Mockito 測(cè)試?

  • 測(cè)試控制器中的輔助方法或私有邏輯
  • 驗(yàn)證控制器內(nèi)復(fù)雜的條件判斷或數(shù)據(jù)處理流程
責(zé)任編輯:武曉燕 來(lái)源: Springboot全家桶實(shí)戰(zhàn)案例
相關(guān)推薦

2009-02-04 09:22:40

穩(wěn)定性服務(wù)器測(cè)試

2019-06-17 15:48:51

服務(wù)器測(cè)試方法軟件

2020-07-28 08:07:14

ElasticSear

2013-05-23 16:00:20

負(fù)載均衡網(wǎng)絡(luò)優(yōu)化網(wǎng)絡(luò)升級(jí)

2023-04-26 18:36:13

2011-07-28 16:06:13

MongoDBAutoShardinReplication

2019-04-30 10:15:40

蘋(píng)果 iOS系統(tǒng)

2018-06-27 16:54:11

紅帽Linux 6.10企業(yè)

2011-07-28 16:17:10

2010-08-11 09:08:51

KDE 4.5.0

2012-04-12 13:48:37

無(wú)線網(wǎng)絡(luò)

2021-01-18 09:43:58

Node.js前端服務(wù)端

2022-09-15 08:33:27

安全生產(chǎn)系統(tǒng)Review

2023-06-30 08:43:36

2023-09-07 15:16:06

軟件開(kāi)發(fā)測(cè)試

2010-08-14 09:46:05

2011-12-21 09:46:46

程序員

2009-07-27 10:08:14

2011-04-27 21:54:45

2011-08-01 11:03:15

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

最好看的中文字幕| 久久免费一级片| 中文字幕乱码在线观看| 亚洲影视一区| 日韩av影片在线观看| 四虎永久在线精品无码视频| 在线观看免费黄视频| 国产精品自拍三区| 欧美在线精品免播放器视频| 亚洲欧美综合7777色婷婷| 亚洲精品在线播放| 91福利小视频| 男人添女荫道口女人有什么感觉| 深夜福利在线视频| 激情国产一区二区| 欧美一级免费视频| 国产一二三区精品| 在线观看欧美理论a影院| 91麻豆精品国产91久久久使用方法 | 中文字幕欧美日韩一区二区| 日韩专区第一页| 激情综合五月婷婷| 欧美性受xxxx黑人猛交| 国产精品白丝喷水在线观看| 女厕嘘嘘一区二区在线播放 | www.精品在线| 激情aⅴ欧美一区二区欲海潮| 中文字幕av一区二区三区| 国产三区二区一区久久| 国产精品视频第一页| 性欧美xxxx大乳国产app| 欧美成人在线网站| 91无套直看片红桃在线观看| 亚洲精品亚洲人成在线| 亚洲精品在线三区| 一起草最新网址| 国产精品亚洲成在人线| 色婷婷香蕉在线一区二区| 日本xxxxxxxxxx75| 中文字幕伦理免费在线视频| 国产精品国产三级国产| 日韩av一区二区三区美女毛片| 欧美一级性视频| 国产精品77777竹菊影视小说| 国产精品久久二区| 国产亚洲欧美日韩高清| 美女黄网久久| 国产99久久精品一区二区永久免费| 精品无码人妻一区二区三区品| 中文字幕人成人乱码| 久久色精品视频| 日韩在线视频免费看| sdde在线播放一区二区| 亚洲无限av看| 免费看日本黄色片| 神马久久一区二区三区| 亚洲欧美日韩国产中文| 女人被狂躁c到高潮| 欧美大胆视频| 亚洲欧美一区二区三区久久| 国产特黄级aaaaa片免| 亚洲宅男一区| 一区二区在线免费视频| 调教驯服丰满美艳麻麻在线视频| 精品99在线| 中文字幕精品国产| 国产大屁股喷水视频在线观看| 欧美一区二区性| 日韩中文字幕视频| 性欧美疯狂猛交69hd| 欧美一区不卡| 久久久久久美女| 中日韩黄色大片| 国产毛片久久| 国产精品直播网红| 99热这里只有精品5| 国产成人高清在线| 国产一区二区三区av在线| 色av男人的天堂免费在线| 久久久精品天堂| 久久免费视频2| 欧美aaaxxxx做受视频| 亚洲va国产天堂va久久en| 免费无码国产v片在线观看| 亚洲精品一级二级| 91精品国产综合久久久蜜臀粉嫩| 极品人妻一区二区| 日本久久成人网| 在线亚洲男人天堂| www.毛片com| 国产日韩一区二区三区在线| 国产精品久久久久久久久久久不卡| 中文天堂在线视频| 国产99久久久久久免费看农村| 精品久久久久久中文字幕动漫 | 99久久香蕉| 亚洲人成网站免费播放| 99久久婷婷国产综合| 91久久午夜| 国产精品嫩草视频| 免费看黄网站在线观看| 国产精品嫩草影院av蜜臀| 国产a级黄色大片| 欧美成人性网| 日韩欧美国产综合| 91激情视频在线观看| 国模 一区 二区 三区| 青青在线视频一区二区三区| 国产精品午夜福利| 久久久久久久网| 天堂а√在线中文在线 | 91精品国产自产在线观看永久| 亚洲av无码乱码在线观看性色| 久久久精品免费免费| 菠萝蜜视频在线观看入口| 国模冰冰炮一区二区| 日韩一区二区在线看片| аⅴ天堂中文在线网| 影音先锋久久久| 91牛牛免费视频| 北岛玲一区二区三区| 天天综合网天天综合色| 91香蕉国产线在线观看| 日韩成人三级| 国产成人小视频在线观看| 欧美熟妇另类久久久久久不卡| 中文字幕在线一区免费| 久久久久久久片| 伊甸园亚洲一区| 国内精品久久久久影院 日本资源 国内精品久久久久伊人av | 国产成人综合一区二区三区| 风流少妇一区二区三区91| 最新中文字幕一区二区三区 | 亚洲欧美一区二区三区四区五区| 日韩精品电影一区亚洲| 六月婷婷久久| 蜜桃视频动漫在线播放| 精品国产一区二区国模嫣然| 亚洲国产美女视频| 韩国成人福利片在线播放| 五月天亚洲综合情| 欧美日韩视频网站| 亚洲女人天堂色在线7777| 青青草成人av| 91麻豆精品在线观看| 国产97在线 | 亚洲| 久久成人福利| 91精品国产高清| 五月婷婷开心中文字幕| 五月婷婷欧美视频| 精品人妻一区二区三区日产乱码卜| 极品av少妇一区二区| 国产日韩一区二区| 国产亚洲成av人片在线观看 | 丁香在线视频| 色国产精品一区在线观看| 中文字幕国产专区| 日韩激情视频在线观看| 色综合影院在线观看| 国产成人77亚洲精品www| 日日骚久久av| 国产口爆吞精一区二区| 亚洲精品欧美专区| 中文字幕在线国产| 国产欧美一级| 欧美日韩国产高清视频| 成人高清一区| 久久亚洲精品成人| 亚洲第一页在线观看| 精品国产乱码久久久久酒店| 亚洲欧美视频在线播放| 日韩av中文字幕一区二区| 亚洲一区二区三区乱码| 精品国产亚洲一区二区三区在线 | 亚洲老司机av| 欧美另类高清videos的特点| 国产精品高潮呻吟| 蜜桃视频无码区在线观看| 亚洲日韩视频| 日韩国产伦理| 日韩一区二区三区色| 亚洲91精品在线| 国产午夜在线观看| 91精品久久久久久蜜臀| 日韩特黄一级片| 国产色产综合色产在线视频| 亚洲第一色av| 国产日韩1区| 中文字幕不卡每日更新1区2区| 中文字幕一区日韩精品 | 日本中文在线播放| 中文字幕成人av| 国产chinesehd精品露脸| 久久久久国产精品午夜一区| 在线观看免费黄色片| 欧美a一欧美| 成人免费黄色网| 激情黄产视频在线免费观看| 色婷婷久久一区二区| 黄色av免费观看| 欧美日韩视频专区在线播放| 久草免费新视频| 国产精品美女久久久久久久| 亚洲色图欧美另类| 美国三级日本三级久久99| 日韩小视频网站| 不卡日本视频| 狠狠色噜噜狠狠狠狠色吗综合| 欧美风情在线视频| 欧美亚洲在线视频| 色图在线观看| 在线激情影院一区| 午夜在线观看视频18| 欧美一区二区三区性视频| 国产剧情在线视频| 亚洲一区二区精品3399| 日韩国产第一页| 久久久电影一区二区三区| 好吊操视频这里只有精品| 麻豆精品视频在线观看免费| 少妇av一区二区三区无码| 午夜欧美在线| 亚洲国产精品久久久久婷婷老年| 高潮久久久久久久久久久久久久| 91精品久久久久久久久| av有声小说一区二区三区| 久久久在线免费观看| fc2ppv国产精品久久| 正在播放亚洲1区| 欧美捆绑视频| 日韩精品电影网| 欧美亚洲精品在线观看| 精品久久久久一区| 性网爆门事件集合av| 69堂成人精品免费视频| 中文字幕有码无码人妻av蜜桃| 色综合 综合色| 国内自拍视频在线播放| 黄网动漫久久久| 黄色小视频在线免费看| 一区二区三区视频在线看| 伊人在线视频观看| 亚洲人妖av一区二区| 久久久精品少妇| 中文字幕在线观看一区| 亚洲天堂av中文字幕| 欧美国产丝袜视频| 永久免费毛片在线观看| 国产欧美日韩另类视频免费观看| 一级黄色片大全| 国产三级久久久| 91精品国自产在线| 亚洲国产精品二十页| 夫妇露脸对白88av| 国产精品伦一区| 一区二区国产精品精华液| 亚洲女爱视频在线| 欧美极品视频在线观看| 亚洲成人动漫在线观看| 午夜精品三级久久久有码| 一本久久精品一区二区| 青青国产在线视频| 欧美老人xxxx18| 国产伦精品一区二区三区免.费| 6080午夜不卡| 国产高清视频免费观看| 亚洲成年人在线播放| 亚洲欧洲精品视频| 在线观看久久久久久| 欧美尤物美女在线| 欧美大秀在线观看| 澳门成人av网| 国产一区玩具在线观看| 日韩08精品| 精品一区久久久久久| 精品一区二区三区在线| 99中文字幕在线观看| 尹人成人综合网| 天天色综合天天色| 国产电影精品久久禁18| 成人免费无码大片a毛片| 国产欧美一区二区精品婷婷| 欧美风情第一页| 亚洲国产一区在线观看| 在线免费观看av网址| 91精品中文字幕一区二区三区| 刘亦菲久久免费一区二区| 亚洲男人第一网站| www.久久ai| 欧美与欧洲交xxxx免费观看| 欧美在线se| 久久av二区| 999久久久亚洲| 3d动漫一区二区三区| 美女mm1313爽爽久久久蜜臀| 欧美成人精品一区二区综合免费| 国产午夜亚洲精品不卡| 婷婷色中文字幕| 欧美午夜电影在线播放| 亚洲女同志亚洲女同女播放| 一区二区三区四区精品| 欧美xxxx做受欧美88bbw| 国产精品18久久久久久麻辣| 日本综合精品一区| 亚洲人体一区| 一区二区精品| 被黑人猛躁10次高潮视频| 久久免费的精品国产v∧| 国产乱国产乱老熟300| 欧美三区在线观看| 深夜福利在线观看直播| 久久成人亚洲精品| 国产一区二区三区朝在线观看| 国产高清一区视频| 香蕉视频官网在线观看日本一区二区| 日本久久久精品视频| 国产精品香蕉一区二区三区| 成人在线一级片| 午夜不卡av在线| 亚洲国产精品国自产拍久久| 精品国产一区二区三区四区在线观看 | 精品成人乱色一区二区| 亚洲av无码一区二区三区dv | 天天操夜夜操av| 欧美最新大片在线看| 婷婷五月综合激情| 欧美日本亚洲视频| 疯狂欧洲av久久成人av电影| 日韩美女一区| 日韩精品一级中文字幕精品视频免费观看| 久久无码专区国产精品s| 亚洲三级在线看| 91黄色在线视频| 最近2019年日本中文免费字幕| 亚洲欧美韩国| 久久青青草原| 国产模特精品视频久久久久| 国产老熟女伦老熟妇露脸| 亚洲国产美国国产综合一区二区| 99热这里只有精品在线观看| 久久精品视频中文字幕| 亚洲免费一区| 99热一区二区三区| 极品少妇xxxx精品少妇| 亚洲天堂一级片| 日韩一区二区中文字幕| 亚洲妇熟xxxx妇色黄| 97欧洲一区二区精品免费| 欧美日韩国产在线一区| 伊人av在线播放| 亚洲国产美女搞黄色| 女人18毛片一区二区三区| 97在线精品国自产拍中文| 欧美高清视频看片在线观看| 欧美日本视频在线观看| 91麻豆精品视频| 综合久久中文字幕| 色久欧美在线视频观看| 久久gogo国模啪啪裸体| 日本精品福利视频| 成人免费视频网站在线观看| 日本网站在线免费观看| 国产午夜精品久久久| 欧美日韩五码| 伊人狠狠色丁香综合尤物| 国产一区中文字幕| 国产一级在线视频| 精品偷拍各种wc美女嘘嘘| 日韩三区免费| 免费看啪啪网站| 国产成人精品三级| 日本一级片免费看| 国产午夜精品视频免费不卡69堂| 91超碰碰碰碰久久久久久综合| 亚洲国产精品视频一区| 国产剧情av麻豆香蕉精品| 国产性xxxx高清| 国产一区二区成人| av在线成人| 欧美 国产 综合| 国产精品无码永久免费888| av网站免费播放| 欧美在线视频一区二区| 91精品在线观看国产| 国产性生活毛片| 欧美性感一区二区三区| 婷婷av在线| 亚洲成人a**址| 成人少妇影院yyyy| 中文字幕日本视频| 久久99视频免费| 精品高清在线| 无码av免费精品一区二区三区| 色婷婷亚洲婷婷| 国内高清免费在线视频| 日韩欧美在线电影| 成人黄色av电影| 一区不卡在线观看| 91精品国产色综合久久不卡98口 | 日韩有码视频在线|