亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Mockito如何mock靜態(tài)方法問題

 更新時間:2025年02月25日 10:53:16   作者:cab5  
本文介紹了如何在Mockito 3.4.0版本及以上版本中mock靜態(tài)方法,包括如何在pom文件中添加相關(guān)jar包、如何使用Mockito.mockStatic(Class mockClass)方法以及注意事項等

Mockito如何mock靜態(tài)方法

在實際工作當(dāng)中,我們經(jīng)常會遇到需要對靜態(tài)方法進(jìn)行 mock 的情況。在 mockito 2.x 的時代,我們需要借助 powmock 才能實現(xiàn)。

當(dāng) mockito 進(jìn)化到了 3.4.0 版本以后,也開始對靜態(tài)方法 mock 進(jìn)行了支持(主要是通過 mockito-inline 包)。

簡單的介紹就到這里,下面讓我們進(jìn)入主題吧。

1.首先確保pom文件中

mockito 相關(guān) jar 包的版本(這里我用的版本是 3.7.7),如下:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>3.7.7</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>3.7.7</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>3.7.7</version>
    <scope>test</scope>
</dependency>
<dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>4.13</version>
     <scope>test</scope>
 </dependency>

2.使用方式

Mockito.mockStatic(Class mockClass),如下:

// 這里 DateUtil 內(nèi)提供了靜態(tài)方法
MockedStatic<DateUtil> dateUtil = mockStatic(DateUtil.class);

示例:

import static org.mockito.Mockito.mockStatic;

@RunWith(MockitoJUnitRunner.class)
public class AlphaServiceTest {

    @Test
    public void testHttp() {
        ...
        
        MockedStatic<HTTPClient> httpClient = mockStatic(HTTPClient.class);
        httpClient.when(() -> HTTPClient.sendPost("xxx/zzz/ccc", "hello")).thenReturn("success");
        
        ...
        
        // 關(guān)閉
        httpClient.close();
    }
    

這樣基本上就 OK 了。

唯一需要注意下的就是 httpClient.close(),這個問題會在「3.其他」中 “錯誤提示 static mocking is already registered in the current thread To create a new mock, the existing static mock registration must be deregistered” 進(jìn)行詳細(xì)說明)

3.其他

如果項目中未引入 mockito-inline,會出現(xiàn)如下錯誤信息:

org.mockito.exceptions.base.MockitoException: 
The used MockMaker SubclassByteBuddyMockMaker does not support the creation of static mocks

Mockito's inline mock maker supports static mocks based on the Instrumentation API.
You can simply enable this mock mode, by placing the 'mockito-inline' artifact where you are currently using 'mockito-core'.
Note that Mockito's inline mock maker is not supported on Android.

    at com.annoroad.order.service.PreOrderServiceTestCase.testSaveClinicalFreeSuccess1(PreOrderServiceTestCase.java:86)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

錯誤提示

static mocking is already registered in the current thread To create a new mock, the existing static mock registration must be deregistered

當(dāng)多個單元測試都使用了同一個 static mock 對象,且使用完成后都沒有進(jìn)行 close。此時,若這幾個單元測試用一起執(zhí)行,第一個單元測試占用了 static mock 對象,第二個單元測試就沒有辦法再占用了。

如果出現(xiàn)了這種情況,解決辦法也很簡單,就是關(guān)閉 static mock 對象,如下:

import static org.mockito.Mockito.mockStatic;

@RunWith(MockitoJUnitRunner.class)
public class AlphaServiceTest {

    @Test
    public void testHttp1() {
        ...
        
        MockedStatic<HTTPClient> httpClient = mockStatic(HTTPClient.class);
        httpClient.when(() -> HTTPClient.sendPost("xxx/zzz/ccc", "hello")).thenReturn("success");
        
        ...

		httpClient.close();
    }
    
    @Test
    public void testHttp2() {
        ...
        
        MockedStatic<HTTPClient> httpClient = mockStatic(HTTPClient.class);
        httpClient.when(() -> HTTPClient.sendPost("xxx/zzz/ccc", "hello")).thenReturn("success");
        
        ...

		httpClient.close();
    }
    
    @Test
    public void testHttp3() {
        ...
        
        MockedStatic<HTTPClient> httpClient = mockStatic(HTTPClient.class);
        httpClient.when(() -> HTTPClient.sendPost("xxx/zzz/ccc", "hello")).thenReturn("success");
        
        ...
		
		httpClient.close();
    }

如果你的很多單元測試中都用到了 mockStatic(HTTPClient.class),且覺得在每個單元測試當(dāng)中都寫一遍 mockStatic()…close() 很低效,可以采用下邊的方式:

import static org.mockito.Mockito.mockStatic;

@RunWith(MockitoJUnitRunner.class)
public class AlphaServiceTest {
	private MockedStatic<HttpClietn> httpClient;

	// 每個單元測試啟動前,先執(zhí)行該方法(高版本中 @Before 被替換成 @BeforeEach)
    @Before
    public void setUp() {
        this.httpClient = mockStatic(HTTPClient.class);
    }
    
	// 每個單元測試執(zhí)行完成后,執(zhí)行該方法(高版本中 @After 被替換成 @AfterEach)
    @After
    public void teardown() {
        this.httpClient.close();
    }

    @Test
    public void testHttp1() {
        ...
        
        httpClient.when(() -> HTTPClient.sendPost("xxx/zzz/ccc", "hello")).thenReturn("success");
        
        ...
    }
    
    @Test
    public void testHttp2() {
        ...
        
        httpClient.when(() -> HTTPClient.sendPost("xxx/zzz/ccc", "hello")).thenReturn("success");
        
        ...
    }
    
    @Test
    public void testHttp3() {
        ...
        
        httpClient.when(() -> HTTPClient.sendPost("xxx/zzz/ccc", "hello")).thenReturn("success");
        
        ...
    }

這樣就清爽多了 ~:)

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringCloud_Sleuth分布式鏈路請求跟蹤的示例代碼

    SpringCloud_Sleuth分布式鏈路請求跟蹤的示例代碼

    Spring Cloud Sleuth是一款針對Spring Cloud的分布式跟蹤工具,本文通過實例代碼介紹了SpringCloud_Sleuth分布式鏈路請求跟蹤,感興趣的朋友跟隨小編一起看看吧
    2023-02-02
  • jdk中String類設(shè)計成final的原由

    jdk中String類設(shè)計成final的原由

    為什么jdk中把 String 類設(shè)計成final,主要是為了“ 效率 ”和“安全性”的緣故,若 String 允許被繼承, 由于它的高度被使用率, 可能會降低程序的性能,所以String被定義成final,需要了解的朋友可以參考下
    2013-01-01
  • 基于Springboot實現(xiàn)送水公司信息管理系統(tǒng)

    基于Springboot實現(xiàn)送水公司信息管理系統(tǒng)

    這篇文章主要介紹了基于Springboot實現(xiàn)送水公司信息管理,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01
  • Spring 中優(yōu)雅的獲取泛型信息的方法

    Spring 中優(yōu)雅的獲取泛型信息的方法

    這篇文章主要介紹了Spring 中優(yōu)雅的獲取泛型信息的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • SpringBoot自定義Starter與自動配置實現(xiàn)方法詳解

    SpringBoot自定義Starter與自動配置實現(xiàn)方法詳解

    在Spring Boot官網(wǎng)為了簡化我們的開發(fā),已經(jīng)提供了非常多場景的Starter來為我們使用,即便如此,也無法全面的滿足我們實際工作中的開發(fā)場景,這時我們就需要自定義實現(xiàn)定制化的Starter
    2023-02-02
  • 淺談Zookeeper開源客戶端框架Curator

    淺談Zookeeper開源客戶端框架Curator

    這篇文章主要介紹了淺談Zookeeper開源客戶端框架Curator的相關(guān)內(nèi)容,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • SpringBoot參數(shù)校驗的方法總結(jié)

    SpringBoot參數(shù)校驗的方法總結(jié)

    今天帶大家學(xué)習(xí)SpringBoot參數(shù)校驗的方法,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • java后臺批量下載文件并壓縮成zip下載的方法

    java后臺批量下載文件并壓縮成zip下載的方法

    這篇文章主要為大家詳細(xì)介紹了java后臺批量下載文件并壓縮成zip下載的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • spring mvc 和ajax異步交互完整實例代碼

    spring mvc 和ajax異步交互完整實例代碼

    本篇文章主要介紹了spring mvc 和ajax異步交互完整實例代碼,簡單的AJAX+SpringMVC的異步交互小例子,有興趣的可以了解一下。
    2017-02-02
  • 關(guān)于微服務(wù)使用Dubbo設(shè)置的端口和server.port的區(qū)別

    關(guān)于微服務(wù)使用Dubbo設(shè)置的端口和server.port的區(qū)別

    這篇文章主要介紹了關(guān)于微服務(wù)使用Dubbo設(shè)置的端口和server.port的區(qū)別,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12

最新評論