PowerMock簡(jiǎn)介

PowerMock擴(kuò)展自Mockito,通過(guò)Java反射機(jī)制解決Mockito的一些問(wèn)題,比如:在模擬final,static或者private方法上的不足。

1. Maven依賴

<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>1.6.4</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito</artifactId>
    <version>1.6.4</version>
    <scope>test</scope>
</dependency>

為了使用PowerMockito,我們需要在被測(cè)試類上添加以下兩個(gè)注解

@RunWith(PowerMockRunner.class)
@PrepareForTest(fullyQualifiedNames = "com.baeldung.powermockito.introduction.*")

@PrepareForTest注解中的fullyQualifiedNames代表一組我們想要mock的類的全限定名。在上面的例子中,我們使用了帶有通配符的包名,這樣,PowerMockito就會(huì)準(zhǔn)備好com.baeldung.powermockito.introduction包下的所有的類,使他們可以用來(lái)mock。

2. 模擬構(gòu)造器和final方法

本節(jié),我們展示在使用new操作符實(shí)例化類時(shí),如何得到一個(gè)mock對(duì)象,而非真實(shí)的對(duì)象,并使用mock對(duì)象來(lái)模擬final方法。

public class CollaboratorWithFinalMethods {
    public final String helloMethod() {
        return "Hello World!";
    }
}

調(diào)用無(wú)參構(gòu)造器,返回mock對(duì)象

CollaboratorWithFinalMethods mock = mock(CollaboratorWithFinalMethods.class);
whenNew(CollaboratorWithFinalMethods.class).withNoArguments().thenReturn(mock);
CollaboratorWithFinalMethods collaborator = new CollaboratorWithFinalMethods();
verifyNew(CollaboratorWithFinalMethods.class).withNoArguments();

調(diào)用final方法

when(collaborator.helloMethod()).thenReturn("Hello Baeldung!");
String welcome = collaborator.helloMethod();
Mockito.verify(collaborator).helloMethod();
assertEquals("Hello Baeldung!", welcome);

3. 模擬static方法

public class CollaboratorWithStaticMethods {
    public static String firstMethod(String name) {
        return "Hello " + name + " !";
    }
 
    public static String secondMethod() {
        return "Hello no one!";
    }
 
    public static String thirdMethod() {
        return "Hello no one again!";
    }
}

為了模擬static方法,需要使用mockStatic注冊(cè)類

    mockStatic(CollaboratorWithStaticMethods.class);

完整的測(cè)試代碼如下

    @Test(expected = RuntimeException.class)
    public void givenStaticMethods_whenUsingPowerMockito_thenCorrect() {
        mockStatic(CollaboratorWithStaticMethods.class);

        when(CollaboratorWithStaticMethods.firstMethod(Mockito.anyString())).thenReturn("Hello Baeldung!");
        when(CollaboratorWithStaticMethods.secondMethod()).thenReturn("Nothing special");
        when(CollaboratorWithStaticMethods.thirdMethod()).thenThrow(RuntimeException.class);

        String firstWelcome = CollaboratorWithStaticMethods.firstMethod("Whoever");
        String secondWelcome = CollaboratorWithStaticMethods.firstMethod("Whatever");

        assertEquals("Hello Baeldung!", firstWelcome);
        assertEquals("Hello Baeldung!", secondWelcome);

        verifyStatic(times(2));
        CollaboratorWithStaticMethods.firstMethod(Mockito.anyString());

        verifyStatic(Mockito.never());
        CollaboratorWithStaticMethods.secondMethod();

        CollaboratorWithStaticMethods.thirdMethod();
    }

注意:verifyStatic()要在具體要校驗(yàn)的方法前面

4. 局部校驗(yàn)

public class CollaboratorForPartialMocking {
    public static String staticMethod() {
        return "Hello Baeldung!";
    }
 
    public final String finalMethod() {
        return "Hello Baeldung!";
    }
 
    private String privateMethod() {
        return "Hello Baeldung!";
    }
 
    public String privateMethodCaller() {
        return privateMethod() + " Welcome to the Java world.";
    }
}

4.1 局部模擬static方法

我們使用spy(XXX.class)來(lái)局部模擬CollaboratorForPartialMocking類,并為static方法設(shè)置預(yù)期

spy(CollaboratorForPartialMocking.class);
when(CollaboratorForPartialMocking.staticMethod()).thenReturn("I am a static mock method.");

校驗(yàn)如下

returnValue = CollaboratorForPartialMocking.staticMethod();
verifyStatic();
CollaboratorForPartialMocking.staticMethod();
assertEquals("I am a static mock method.", returnValue);

4.2 局部模擬final和private方法

我們使用spy(object)來(lái)局部模擬CollaboratorForPartialMocking對(duì)象

CollaboratorForPartialMocking collaborator = new CollaboratorForPartialMocking();
CollaboratorForPartialMocking mock = spy(collaborator);

final方法

when(mock.finalMethod()).thenReturn("I am a final mock method.");
returnValue = mock.finalMethod();
verify(mock,times(3)).finalMethod();
assertEquals("I am a final mock method.", returnValue);

private方法

when(mock, "privateMethod").thenReturn("I am a private mock method.");
returnValue = mock.privateMethodCaller();
verifyPrivate(mock).invoke("privateMethod");
assertEquals("I am a private mock method. Welcome to the Java world.", returnValue);

與final方法不同的是,private方法無(wú)法直接被調(diào)用。PowerMock使用privateMethodCaller作為代理,調(diào)用被測(cè)試類的private方法。

完整的測(cè)試代碼如下:

    @Test
    public void givenPartialMocking_whenUsingPowerMockito_thenCorrect() throws Exception {
        String returnValue;

        spy(CollaboratorForPartialMocking.class);
        when(CollaboratorForPartialMocking.staticMethod()).thenReturn("I am a static mock method.");
        returnValue = CollaboratorForPartialMocking.staticMethod();
        verifyStatic();
        CollaboratorForPartialMocking.staticMethod();
        assertEquals("I am a static mock method.", returnValue);

        CollaboratorForPartialMocking collaborator = new CollaboratorForPartialMocking();
        CollaboratorForPartialMocking mock = spy(collaborator);

        when(mock.finalMethod()).thenReturn("I am a final mock method.");
        returnValue = mock.finalMethod();
        verify(mock,times(3)).finalMethod();
        assertEquals("I am a final mock method.", returnValue);

        when(mock, "privateMethod").thenReturn("I am a private mock method.");
        returnValue = mock.privateMethodCaller();
        verifyPrivate(mock).invoke("privateMethod");
        assertEquals("I am a private mock method. Welcome to the Java world.", returnValue);
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ??Java單元測(cè)試框架主要有JUnit和TestNG,常用的Mock框架主要有EasyMock、Mockito和...
    SeanPenn閱讀 1,044評(píng)論 0 0
  • 本文為Powermock官方文檔Mockito篇的中文翻譯原文:https://github.com/powerm...
    卻把清梅嗅閱讀 5,761評(píng)論 0 10
  • 什么是單元測(cè)試? 單元測(cè)試(又稱為模塊測(cè)試, Unit Testing)是針對(duì)程序模塊(軟件設(shè)計(jì)的最小單位)來(lái)進(jìn)行...
    常曉csc閱讀 9,613評(píng)論 0 6
  • 一.前言 ??關(guān)于這篇文章的起源,是第三次思沃大講堂的作業(yè)的題目中,有這樣一段話 把前兩問(wèn)做的類集成起來(lái),寫一個(gè)集...
    廖雪青閱讀 2,798評(píng)論 0 7
  • PowerMockito簡(jiǎn)介(以上都是自我琢磨,錯(cuò)誤之處請(qǐng)批評(píng)指正) 在實(shí)際項(xiàng)目中寫單元測(cè)試的過(guò)程中我們會(huì)發(fā)現(xiàn)需要...
    盛京最帥得仔閱讀 1,286評(píng)論 0 2

友情鏈接更多精彩內(nèi)容