SpringBoot使用Powermockito mock靜態方法/私有方法 - 第342篇

2021-02-14 SpringBoot

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

國內最全的Spring Boot系列之三

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

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

Mock工具之Mockito - 第337篇

Spring Boot中使用Mockito - 第338篇

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

Mockito中捕獲mock對象方法的調用參數[SpringBoot]

SpringBoot使用Mockito mock靜態方法/私有方法 - 第341篇

悟纖:師傅,我最近發現一個傢伙,特別厲害。

師傅:是不是發現了新大陸了。

悟纖:嗯,我最近看到一個更牛逼的傢伙Poowermockito增強了mockito的能力。

師傅:那徒兒和為師分享一下你學習的心得唄。

悟纖:那徒兒就獻醜了。

 

一、Mockito和PowerMock的簡介

Mocktio和PowerMock都是Mock的工具類,主要是Java的類庫,Mock就是偽裝的意思。他們適用於單元測試中,對於單元測試來說,我們不希望依賴於第三方的組件,比如資料庫、Webservice等。在寫單元測試的時候,我們如果遇到了這些需要依賴第三方的情況,我們可以使用mock的技術,偽造出來我們自己想要的結果。對於Java而言,mock的對象主要是Java 方法和Java類。

 

二、Mockito和PowerMock的區別

PowerMock是Mockito的一種增強,PowerMock可以調用Mockito的方法,但是對於Mocktio不能Mock的對象或者方法,我們可以使用PowerMock來實現。比如Mockito不能用於static Method, final method, 枚舉類, private method,這些我們都可以用powermock來實現,當然對於新版的Mockito配合上mockito-inline能解決部分的問題,這個具體看前面的章節《SpringBoot使用Mockito mock靜態方法/私有方法》。

 

二、Mockito和PowerMock版本對應關係

Mockito

PowerMock

2.8.9+

2.x

2.8.0-2.8.9

1.7.x

2.7.5

1.7.0RC4

2.4.0

1.7.0RC2

2.0.0-beta -  2.0.42-beta

1.6.5-1.7.0RC

1.10.8 - 1.10.x

1.6.2 - 2.0

1.9.5-rc1 - 1.9.5

1.5.0 - 1.5.6

1.9.0-rc1 & 1.9.0

1.4.10 - 1.4.12

1.8.5

1.3.9 - 1.4.9

1.8.4

1.3.7 & 1.3.8

1.8.3

1.3.6

1.8.1 & 1.8.2

1.3.5

1.8

1.3

1.7

1.2.5

 

三、PowerMock的使用

3.1 單元測試類上的註解說明

在 Spring Boot 的測試套件中,需要添加@RunWith(SpringRunner.class) 和 @SpringBootTest 註解。

但是 PowerMock 需要添加@RunWith(PowerMockRunner.class) 註解。@RunWith 註解只能有一個,解決方案是使用 @PowerMockRunnerDelegate 註解,同時使用@PowerMockIgnore 註解避免報錯:

@SpringBootTest
@RunWith(PowerMockRunner.class)@PowerMockRunnerDelegate(SpringRunner.class)@PowerMockIgnore({"javax.management.*", "javax.net.ssl.*"})
@PrepareForTest({UserController.class})public class TestStaticMethod {}

3.2 mock靜態方法

       靜態代碼的編寫和前面章節的《SpringBoot使用Mockito mock靜態方法/私有方法》是一樣的,這裡不重複編寫了,主要來看下具體的mock代碼編寫的區別:

@Beforepublic void setUp() {    PowerMockito.mockStatic(UserController.class);    PowerMockito.when(UserController.isTrue(any(String.class))).thenReturn(true);}
@Testpublic void verifyStaticMock() { boolean flag = userController.verifyStaticMcok(""); Assert.assertTrue(flag);}

3.3 mock私有方法

       我能在UserController添加一個私有方法:

@GetMapping(value = "/verifyPrivateMethod")public String verifyPrivateMethod(String userName) {    System.out.println("傳入的用戶名:" + userName);    String result = getUserName(userName);    return result;}
private String getUserName(String str) { System.out.println("進入了私有方法" + str); return str;}

       看下我們的mock代碼:

@Testpublic void verifyPrivateMethod() throws Exception {            UserController spy = PowerMockito.spy(userController);        PowerMockito.when(spy, "getUserName", "zhangsan").thenReturn("lisi");    String userName = spy.verifyPrivateMethod("zhangsan");        PowerMockito.verifyPrivate(spy, Mockito.times(1)).invoke("getUserName", "zhangsan");    Assert.assertEquals("lisi", userName);}

       最後提供一下整個測試類:

package com.kfit.springbootmockitodemo;
import com.kfit.springbootmockitodemo.demo.controller.UserController;import org.junit.Assert;import org.junit.Before;import org.junit.Test;import org.junit.runner.RunWith;import org.mockito.Mockito;import org.powermock.api.mockito.PowerMockito;import org.powermock.core.classloader.annotations.PowerMockIgnore;import org.powermock.core.classloader.annotations.PrepareForTest;import org.powermock.modules.junit4.PowerMockRunner;import org.powermock.modules.junit4.PowerMockRunnerDelegate;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;
import static org.mockito.Mockito.*;@SpringBootTest
@RunWith(PowerMockRunner.class)@PowerMockRunnerDelegate(SpringRunner.class)@PowerMockIgnore({"javax.management.*", "javax.net.ssl.*"})
@PrepareForTest({UserController.class})public class TestStaticMethod {
@Autowired private UserController userController;
@Before public void setUp() { PowerMockito.mockStatic(UserController.class); PowerMockito.when(UserController.isTrue(any(String.class))).thenReturn(true); }
@Test public void verifyStaticMock() { boolean flag = userController.verifyStaticMcok(""); Assert.assertTrue(flag); }

@Test public void verifyPrivateMethod() throws Exception { UserController spy = PowerMockito.spy(userController); PowerMockito.when(spy, "getUserName", "zhangsan").thenReturn("lisi"); String userName = spy.verifyPrivateMethod("zhangsan"); PowerMockito.verifyPrivate(spy, Mockito.times(1)).invoke("getUserName", "zhangsan"); Assert.assertEquals("lisi", userName); }
}

四、總結

       為什麼mockito不能mock靜態方法(mockito-inline為什麼可以呢)?mockito使用繼承的方式實現mock的,用CGLIB生成mock對象代替真實的對象進行執行,為了mock實例的方法,你可以在子類中覆蓋它,而static方法是不能被子類覆蓋的,所以mockito不能mock靜態方法。但powermock可以mock靜態方法,因為它直接在字節碼上工作。

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

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

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

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

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

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

大話設計模式之愛你:https://dwz.cn/wqO0MAy7

相關焦點

  • Spring Boot中使用Mockito進行Web測試 - 第339篇
    篇SpringBoot框架開發的優秀的項目「值得收藏學習」 - 第335從Spring整合第三方框架學習Spring Boot - 第336篇Mock工具之Mockito - 第337篇Spring Boot中使用Mockito - 第338篇悟纖:師傅,我上面mock的service層和dao層的例子?
  • Java SPI一探究竟 - 第343篇
    Mock工具之Mockito - 第337篇Spring Boot中使用Mockito - 第338篇Spring Boot中使用Mockito進行Web測試 - 第339篇Mockito中捕獲mock對象方法的調用參數[SpringBoot]SpringBoot使用Mockito mock靜態方法/私有方法
  • python-mock的幾點使用記錄
    mock非靜態方法使用Mock類,將目標方法賦值為Mock(return_value=XXXX),返回固定值默認情況下被mock的方法入參個數及賦值情況不會對返回值產生影響;校驗參數個數,再返回固定值, 需要用create_autospec
  • 合格的後端Coder都應該寫好UT和Mock測試
    本文不討論語法,只介紹一般性的使用規範。   什麼樣的方法不需要 mock本類的需要測試的方法依賴的同類方法,該方法的正確性由該方法自身的 UT 來保證靜態方法,靜態方法由自身的 UT 來保證功能的正確性protected 方法是可以測試的,只要測試代碼類和要測試的類在同一個 package 下面就可以
  • Excel power函數的使用方法,乘方是怎樣計算的?
    本篇將介紹Excel power()函數(乘方)的使用方法,有興趣的朋友可以了解一下!一、前言Excel是我們工作中很常用的表格製作工具,它不僅僅只是用來製作表格,還可以對表格中的數據進行處理。Excel power函數二、Excel power()函數在Excel中,power()函數是使用來計算數值的乘方(也叫:乘冪或次方)的。
  • SpringBoot 優雅停止服務的幾種方法 - 第309篇
    篇布隆過濾器Bloom Filter竟然讓我解決了一個大廠的問題 - 第305篇100G的文件如何讀取 - 第306篇100G的文件如何讀取續集 - 第307篇Java語言的優雅停機 - 第308篇師傅:對於java的shutdown hook有所了解之後,我們還是重點來看看Spring Boot如何優化停止服務吧
  • mock介紹及moco框架搭建使用
    今天距2021年21天這是ITester軟體測試小棧第181次推文
  • SpringBoot單元測試保姆級教程,文末介紹Postman的基本使用
    一般有兩個方法:方法弊端方法一:啟動整個應用,像用戶正常操作一樣。點擊界面按鈕,調用一個 API 等。每次測試都要啟動整個項目方法二:在代碼某個地方寫一個臨時入口,例如 java 的 main 方法,測試某個方法或者某個類。
  • 單元測試不止Junit,會MockMvc才是高手!
    mock 測試。來創建以便測試的測試方法,就是 mock 測試在測試過程中,對於某些不容易構造或者不容易獲取的對象,用一個虛擬的對象來創建以便測試的測試方法,就是* mock 測試*。虛擬的對象就是 mock 對象。mock 對象就是真實對象在調試期間的代替品。2、為什麼使用 mock 測試3、MockMVC 介紹基於 RESTful 風格的 SpringMVC 的測試,我們可以測試完整的 Spring MVC 流程,即從 URL 請求到控制器處理,再到視圖渲染都可以測試。
  • PostMan 之 Mock 接口測試
    測試人員可以通過 mock server 自己去造一個接口來訪問。mock server 可用於模擬真實的接口。收到請求時,它會根據配置返回對應的請求。在前後端分離的大背景下,mock server 在前端開發應用非廣泛,也影響到測試人員。
  • SpringBoot 接口冪等性的實現方案
    冪等函數或冪等方法是指可以使用相同參數重複執行,並能獲得相同結果的函數。這些函數不會影響系統狀態,也不用擔心重複執行會對系統造成改變。二、什麼是接口冪等性在HTTP/1.1中,對冪等性進行了定義。接口超時重複提交: 很多時候 HTTP 客戶端工具都默認開啟超時重試的機制,尤其是第三方調用接口時候,為了防止網絡波動超時等造成的請求失敗,都會添加重試機制,導致一個請求提交多次。消息進行重複消費: 當使用 MQ 消息中間件時候,如果發生消息中間件出現錯誤未及時提交消費信息,導致發生重複消費。
  • 使用MockMVC進行Controller單元測試
    ;import org.mockito.Mock;import org.mockito.Mockito;import org.mockito.MockitoAnnotations;import org.springframework.http.MediaType;import org.springframework.test.web.servlet.MockMvc
  • 面試官:為什麼java中靜態方法不能調用非靜態方法或變量?
    這個可能很多人之前學習jvm的時候都會遇到,屬於一個小問題,寫這篇文章的原因是我在看java相關的面試題目中遇到的,因此順手總結一下:一、例子我們先看效果:我們在靜態方法main中調用非靜態變量或者是方法都會報錯。
  • python 類(3) 私有屬性/方法
    __name = "我是一個私有屬性,實例無法直接訪問"mc = MyClass()print(mc.__name)可以看到,__name雖然看上去像是一個屬性(定義在方法內,且用self.的方式聲明的變量),但是在實際的應用中,我們卻無法用mc.__name方式直接讀取該值.這樣就起到了保護__name屬性的作用.
  • Java中的static關鍵字和靜態變量、靜態方法
    作者: Java進階者 來源:Java進階學習交流一、static關鍵字使用static修飾的變量和方法分別稱為類變量(或稱靜態變量)和類方法(或稱靜態方法),沒有使用static修飾的變量和方法分別稱為實例變量和實例方法
  • Java之抽象方法的使用與及接口中抽象方法的簡單介紹
    接口就是多個類的公共規範,是一中引用數據類型,最重要的內容就是其中的抽象方法。如上圖所示,通過上面這個USB接口,兩臺電腦可以互相傳遞文件,只要符合USB接口的規範,很多設備都可以使用。那麼,如何定義一個接口呢?
  • SpringBoot(五) :spring data jpa 的使用
    08/20/springboot(五)-spring-data-jpa的使用.html如有好文章投稿,請點擊 → 這裡了解詳情在上篇文章《 springboot(二):web綜合開發 》中簡單介紹了一下spring data jpa的基礎性使用,這篇文章將更加全面的介紹spring data jpa 常見用法以及注意事項。
  • 記錄springboot接收post和get兩種方式提交數據的不同方法
    springboot 後端接收 參數問題原因:因ajax使用的是post方式提交,而在springboot的Controller定義的使用的是當ajax使用post方式的應用場景一般都是json格式提交到後臺,方便服務前將json映射到對應javaBean上。當使用post方式提交是Controller的方法可使用@RequestBody進行處理。
  • SpringBoot開發常用的註解及作用
    2,@EnableAutoCfiguration:使用該註解作用就是告訴springboot根據添加jar依賴猜測你想如何配置spring。3,@ComponentScan:組件掃描,自動掃麵包。並把這些類註冊為Bean。