Spring Boot中使用Mockito進行Web測試 - 第339篇

2021-03-02 SpringBoot

相關歷史文章(閱讀本文前,您可能需要先看下之前的系列👇

國內最全的Spring Boot系列之三

2020上半年發文匯總「值得收藏」

Slf4j的前世今生之java日誌框架演化歷史 - 第334篇

SpringBoot框架開發的優秀的項目「值得收藏學習」 - 第335

從Spring整合第三方框架學習Spring Boot - 第336篇

Mock工具之Mockito - 第337篇

Spring Boot中使用Mockito - 第338篇

悟纖:師傅,我上面mock的service層和dao層的例子?我看了下這個web層的,好像不行呢?是不支持嗎?

師傅:Mockito這個還是很成熟的,不支持在這裡是木有的,還是你沒研究到位。

悟纖:歐侯,是這樣子的嗎?

師傅:你這麼聰明伶俐,師傅能忽悠得了你嘛。

悟纖:也對,那我再去好好研究一下。

 

一、概述

       在web應用程式中,對Controller層的測試一般有兩種方法:

(1)發送http請求;

(2)模擬http請求對象;

今天我們來看下如何用Mock對象測試Controller層的代碼。

 

二、準備工作

2.1 版本說明

(1)Spring Boot : 2.4.0

(2)Mockito:3.6.0

 

2.2 新建一個Controller

       這裡我們是基於前面的文章《Spring Boot中使用Mockito》進行編碼。

       如果對於Mockito還不了解的話,可以看《Mock工具之mockito》。

       好了進入正題,我們添加web依賴:

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-web</artifactId></dependency>

然後新建一個UserController:

package com.kfit.springbootmockitodemo.demo.controller;
import com.kfit.springbootmockitodemo.demo.bean.User;import com.kfit.springbootmockitodemo.demo.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;

@RestController@RequestMapping("/user")public class UserController {
@Autowired private UserService userService;
@RequestMapping("/findById") public User findById(int id){ return userService.findById(id); }
}

       這代碼沒啥好講的,spring boot項目的hello代碼了,如果你連spring boot還不懂,那麼我只能……  送你一份我的獨門秘籍了:

《國內最全的Spring Boot系列之一》

https://mp.weixin.qq.com/s/dhGgXrff-p4xcQNO3ON79A

《國內最全的Spring Boot系列之二》

       https://mp.weixin.qq.com/s/kQ01ShwPQoxsBbMC4RlECA

《國內最全的Spring Boot系列之三》

       https://mp.weixin.qq.com/s/wpcc86uoaZnAim6MTRAOGQ

 

三、Mockito使用

       接下來才是本節的重點,請那個板凳認真聽。

3.1 說明

(1)@RunWith

對於web的單元測試,需要使用註解:@RunWith(SpringRunner.class),@RunWith(SpringRunner.class),這是JUnit的註解,通過這個註解讓SprignRunner這個類提供Spring測試上下文。

 

(2)MockMvc

MockMvc對象提供一組工具函數用來執行assert判斷,都是針對web請求的判斷。這組工具的使用方式是函數的鏈式調用,允許程式設計師將多個測試用例連結在一起,並進行多個判斷。

對於MockMvc如何初始化呢?可以使用MockMvcBuilders的build()方法進行構建,所以我們需要使用@Before在單元測試執行之前進行MockMvc對象的初始化:


private MockMvc mockMvc;
@Beforepublic void setupMockMvc(){ mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();}

3.2 來測試一下web api吧

       我們看下整體的代碼吧:

package com.kfit.springbootmockitodemo;
import org.hamcrest.Matchers;import org.junit.Before;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.http.MediaType;import org.springframework.test.context.junit4.SpringRunner;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 org.springframework.web.context.WebApplicationContext;



@SpringBootTest@RunWith(SpringRunner.class)public class TestMockMvc {
@Autowired private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
@Before public void setupMockMvc(){ mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); }
@Test public void testMvc() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/user/findById?id=1")) .andExpect(MockMvcResultMatchers.status().isOk()) ;
}
}

       這裡核心的就是關注testMvc,這裡andExpect()就是就是判斷請求返回的是200,如果不是的話,就會報錯哦:

3.3 報錯WebApplicationContext isrequired

       如果是報錯:java.lang.IllegalArgumentException:WebApplicationContext is required:

       這個錯誤的可能原因就是:

(1)沒有在單元測試類是添加註解@RunWith(SpringRunner.class);

(2)沒有在屬性上WebApplicationContext添加@Autowired;

3.4 中文亂碼

       我們看下現在請求:/user/findById?id=1,返回的信息是:

       如果我們要判斷這個json數據中的name的value是不是「師傅」這個字符串怎麼做呢 ?

@Testpublic void testMvc1() throws Exception {    mockMvc.perform(MockMvcRequestBuilders.get("/user/findById?id=1"))            .andExpect(MockMvcResultMatchers.status().isOk())            .andExpect(MockMvcResultMatchers.content().string(Matchers.containsString("師傅")))            .andExpect(MockMvcResultMatchers.jsonPath("$.name").value("師傅"))    ;}

       在上面的例子中提供了兩種方式進行比對,一種是字符串的包含的方式,另外一種就是使用的jsonPath獲取key的方式。

       一運行就炸了:

       亂的一批,真的是不忍直視,不讓看也不用打「馬賽克」呀。

       怎麼去除「馬賽克」吶,很簡單,只需要添加一個content-type:

@Testpublic void testMvc2() throws Exception {    mockMvc.perform(MockMvcRequestBuilders.get("/user/findById?id=1")                        .accept(MediaType.APPLICATION_JSON_UTF8))
.andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().string(Matchers.containsString("師傅"))) .andExpect(MockMvcResultMatchers.jsonPath("$.name").value("師傅")) ;
}

       本篇文章接到這裡,我們下周《Mockito中捕獲mock對象方法的調用參數》詳解。

新課預告《大話設計模式之愛你一萬年》連載中:

我就是我,是顏色不一樣的煙火。
我就是我,是與眾不同的小蘋果。

à悟空學院:https://t.cn/Rg3fKJD

學院中有Spring Boot相關的課程!點擊「閱讀原文」進行查看!

SpringBoot視頻:http://t.cn/A6ZagYTi

Spring Cloud視頻:http://t.cn/A6ZagxSR

SpringBoot Shiro視頻:http://t.cn/A6Zag7IV

SpringBoot交流平臺:https://t.cn/R3QDhU0

SpringData和JPA視頻:http://t.cn/A6Zad1OH

SpringSecurity5.0視頻:http://t.cn/A6ZadMBe

ShardingJDBC分庫分表:http://t.cn/A6ZarrqS

分布式事務解決方案:http://t.cn/A6ZaBnIr

JVM內存模型調優實戰:http://t.cn/A6wWMVqG

Spring入門到精通:https://t.cn/A6bFcDh4

相關焦點

  • 使用MockMVC進行Controller單元測試
    這個測試套件就可以使用Spring-test庫中的MockMVC了。例如Maven項目的pom.xml中添加如下的依賴<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope
  • Spring Boot 的單元測試和集成測試
    學習如何使用本教程中提供的工具,並在 Spring Boot 環境中編寫單元測試和集成測試。1. 概覽 本文中,我們將了解如何編寫單元測試並將其集成在 Spring Boot 環境中。你可在網上找到大量關於這個主題的教程,但很難在一個頁面中找到你需要的所有信息。我經常注意到初級開發人員混淆了單元測試和集成測試的概念,特別是在談到 Spring 生態系統時。
  • SpringBoot使用Powermockito mock靜態方法/私有方法 - 第342篇
    Mock工具之Mockito - 第337篇Spring Boot中使用Mockito - 第338篇Spring Boot中使用Mockito進行Web測試 - 第339篇Mockito中捕獲mock對象方法的調用參數[SpringBoot]SpringBoot使用Mockito mock靜態方法/私有方法
  • Spring Boot 單元測試
    一、 單元測試的概念概念:單元測試(unit testing),是指對軟體中的最小可測試單元進行檢查和驗證。在Java中單元測試的最小單元是類。單元測試是開發者編寫的一小段代碼,用於檢驗被測代碼的一個很小的、很明確的功能是否正確。執行單元測試,就是為了證明這 段代碼的行為和我們期望是否一致。
  • Spring Boot 和 Spring 到底有啥區別?
    ;/version></dependency>在進行構建期間,所有其他依賴項將自動添加到項目中。另一個很好的例子就是測試庫。我們通常使用Spring Test,JUnit,Hamcrest和Mockito庫。在Spring項目中,我們應該將所有這些庫添加為依賴項。但是在Spring Boot中,我們只需要添加spring-boot-starter-test依賴項來自動包含這些庫。Spring Boot為不同的Spring模塊提供了許多依賴項。
  • 【保姆級教程】Spring Boot 單元測試
    單元測試(unit testing),是指對軟體中的最小可測試單元進行檢查和驗證。在Java中單元測試的最小單元是類。\2. 單元測試是開發者編寫的一小段代碼,用於檢驗被測代碼的一個很小的、很明確的功能是否正確。執行單元測試,就是為了證明這 段代碼的行為和我們期望是否一致。
  • Spring 和 Spring Boot 之間到底有啥區別?
    ><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.0.6.RELEASE</version></dependency
  • 使用redis在SpringCloud getway中進行速率限制
    使用redis在SpringCloud getway中進行速率限制1.依存關係我們將針對較高流量下的速率限制測試示例應用程式。首先,我們需要包括一些依賴項。當然,需要Spring Cloud Gateway啟動器。
  • Spring 和 Spring Boot 最核心的 3 大區別,詳解!
    <dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-web</artifactId>    <version>2.0.6.RELEASE<
  • Spring SPI和Spring Boot SPI - 第345篇
    篇Java SPI一探究竟 - 第343篇前言       在前面的章節《DriverManager SPI分析和Java SPI原理》中,我們通過分析DriverManager的SPI和Java SPI的原理,對於SPI有了一個比較深的了解。
  • Spring Boot中Tomcat、Jetty、Undertow的使用
    Tomcat在我們使用SpringBoot開發WebApi時,會引入spring-boot-starter-web這個starter組件,其自帶了Tomcat容器,所以我們平時新建項目啟動起來,會看見Tomcat相關的一些信息。
  • 合格的後端Coder都應該寫好UT和Mock測試
    (又稱為模塊測試, Unit Testing)是針對程序模塊(軟體設計的最小單位)來進行正確性檢驗的測試工作。程序單元是應用的最小可測試部件。在過程化編程中,一個單元就是單個程序、函數、過程等;對於面向對象編程,最小單元就是方法,包括基類(超類)、抽象類、或者派生類(子類)中的方法。
  • Spring Boot 集成undertow作為web容器
    JBoss就是使用的undertow。由於Undertow的性能和內存使用方面都優於Tomcat,所以現在很多SpringBoot項目放棄了Tomcat,選擇了Undertow。一、先去除tomcat的引用<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web
  • Spring Boot 整合 Thymeleaf
    同時能夠作為靜態引擎,讓開發成員之間更方便協作開發;Spring Boot 官方推薦使用模板,而且 Spring Boot 也為 Thymeleaf 提供了完整的自動化 配置解決方案;Thymeleaf 使用教程請戳 Tutorial: Using Thymeleaf[1],配合 Spring 使用的教程請戳
  • 使用IntelliJ IDEA創建一個Maven的Spring Boot項目
    >spring-boot-starter-web</artifactId> </dependency> </dependencies> <!
  • 江帥帥:精通 Spring Boot 系列 03
    具體的配置參數可以參考官網文檔第 10 章 Appendices:https://docs.spring.io/spring-boot/docs/2.2.2.RELEASE/reference/htmlsingle/#common-application-properties4.
  • spring boot 整合shiro 錯誤
    最近在弄spring boot 整合shiro的。中沒有添加shiro相關的攔截器。凱哥現在用的是spring boot。web.xml沒有。但是凱哥配置了shiro的核心攔截器啊。如下圖:並且使用了@Configuration這個註解了。
  • 2021 最新版 Spring Boot 速記教程
    可以看到,Redis 自動配置類,讀取了以 spring.redis 為前綴的配置,然後加載 redisTemplate 到容器中,然後我們在應用中就能使用 RedisTemplate 來對緩存進行操作~(還有很多細節沒有細說,例如 @ConditionalOnMissingBean 先留個坑(●´∀`●)ノ)
  • 一文搞懂如何在Spring Boot 正確中使用JPA
    這篇文章可以幫助對 JPA 不了解或者不太熟悉的人來在實際項目中正確使用 JPA。另外,我發現網上關於連表查詢這一塊並沒有太多比較有參考價值的博客,所以對這部分也做了詳細的總結,以供大家學習參考項目代碼基於 Spring Boot 最新的 2.1.9.RELEASE 版本構建(截止到這篇文章寫完),另外,新建項目的過程就不多說了。
  • Spring 和 SpringBoot 之間到底有啥區別?
    >spring-boot-starter-web</artifactId><version>2.0.6.RELEASE</version></dependency>在進行構建期間,所有其他依賴項將自動添加到項目中。