国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android單元測試系列(3)-Mock之PowerMock

這篇具有很好參考價(jià)值的文章主要介紹了Android單元測試系列(3)-Mock之PowerMock。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

一、官網(wǎng)

二、Demo示例?

三、PowerMock常用的測試方法

1. Private

1.1 私有變量

1.2 私有方法

2. Final

3. Static


Android單元測試系列(3)-Mock之Mockito_Chris_166的博客-CSDN博客

Android單元測試系列(1)-開篇_Chris_166的博客-CSDN博客

這兩篇中已經(jīng)分別介紹過Mockito的使用和局限性,本篇將介紹PowerMock,用來擴(kuò)展Mockito功能,彌補(bǔ)其局限性(Mockito不能mock private、static方法和類,一些版本不能mock final方法和類),同時(shí)PowerMock還增加了很多反射方法來修改靜態(tài)和非靜態(tài)成員等。

一、官網(wǎng)

PowerMock · GitHub

GitHub - powermock/powermock: PowerMock is a Java framework that allows you to unit test code normally regarded as untestable.



https://github.com/powermock/powermock/wiki/Mockito

PowerMock是依賴Mockito的,所以使用時(shí)要同時(shí)引入,且版本也必須一一對應(yīng)。

PowerMock跟Mockito的版本對應(yīng)關(guān)系如下:

Android單元測試系列(3)-Mock之PowerMock

二、Demo示例?

這里Demo按照Mockito 2.8.9,PowerMock 1.7.x來搭配。

// Gradle依賴

dependencies {

    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.1'

    testImplementation 'junit:junit:4.+'
    testImplementation 'org.mockito:mockito-core:2.8.9'

    testImplementation "org.powermock:powermock-api-mockito2:1.7.1" // 這個(gè)mockito2必須引入,否則的話會(huì)找不到PowerMockito類
    testImplementation "org.powermock:powermock-module-junit4:1.7.1"
    testImplementation 'org.powermock:powermock-core:1.7.1'
    // testImplementation "org.powermock:powermock-module-junit4-rule:1.7.1"
    // testImplementation "org.powermock:powermock-classloading-xstream:1.7.1"


    // androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    //androidTestImplementation "org.mockito:mockito-android:4.4.0"

}

// 被測試的代碼

package com.fanff.unittestdemo.junitdemo;

public class Calculator {
    public int addExact(int x, int y) {
        return x + y;
    }

    public int subtractExact(int x, int y) {
        return x - y;
    }

    public int multiplyExact(int x, int y) {
        return x * y;
    }

    // TODO: zero case
    public int intDivide(int x, int y) {
        if (y == 0) {
            return dealZeroCase();
        } else {
            return x / y;
        }
    }

    private int dealZeroCase() {
        return 0;
    }
}

// 測試代碼

需求:測試intDivide()方法中是否有調(diào)用到dealZero()方法

package com.fanff.unittestdemo.mockdemo;

import com.fanff.unittestdemo.junitdemo.Calculator;

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.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.mockito.Mockito.times;

@RunWith(PowerMockRunner.class)
@PrepareForTest({Calculator.class})
public class CalculatorMockTest {
    @Test
    public void testIntDivide() {
        Calculator calculator = Mockito.spy(Calculator.class);
        calculator.intDivide(1, 0);
    }

    @Test
    public void testPrivateIntDivideMethod() throws Exception {
        Calculator calculatorPowermockObj = PowerMockito.spy(new Calculator());
        calculatorPowermockObj.intDivide(1, 0);
        PowerMockito.verifyPrivate(calculatorPowermockObj, times(1)).invoke("dealZeroCase"); // Pass
    }
}

這里說明幾點(diǎn):

1.? @RunWith(PowerMockRunner.class) :這里使用的Runner是PowerMockRunner,這樣就可以與Mokito兼容了,即Mokito里的方法在這里也都是可以正常使用的;

2.?@PrepareForTest({Calculator.class}):務(wù)必記得加上這個(gè)PrepareForTest的注解,否則進(jìn)行verify測試的時(shí)候怎么測試都是pass的,如下沒有寫這個(gè)注解,verifyPrivate()怎么測試都是pass

@RunWith(PowerMockRunner.class)
// @PrepareForTest({Calculator.class})
public class CalculatorMockTest {
    @Test
    public void testPrivateIntDivideMethod() throws Exception {
        Calculator calculatorPowermockObj = PowerMockito.spy(new Calculator());
        calculatorPowermockObj.intDivide(8, 8);
        // 如下測試,預(yù)期應(yīng)該是fail的,但是居然實(shí)際測試為pass,因?yàn)闆]有加注解@PrepareForTest({Calculator.class})
        PowerMockito.verifyPrivate(calculatorPowermockObj, times(6)).invoke("dealZeroCase");
    }
}

Android單元測試系列(3)-Mock之PowerMock

三、PowerMock常用的測試方法

主要來看看PowerMock相對Mockito擴(kuò)展的幾點(diǎn):private、final、static.

1. Private

// 被測試的類

package com.fanff.unittestdemo.junitdemo;

import java.util.ArrayList;
import java.util.List;

/**
 * 用來做Powermock的測試.
 * 方法名/類定義/魔數(shù)都是為了簡單隨意寫的,僅僅只是用來介紹每種mock手段而已
 */
public class Person {
    private int mInvaildParam; // 僅僅是用來做私有構(gòu)造方法的說明。私有構(gòu)造方法常用于單例設(shè)計(jì)模式
    private String mName;
    private final List<String> mAddressList = new ArrayList<>();
    private School mInnerSchoolObj;

    private Person(int invaildParam) {
        mInvaildParam = invaildParam;
        System.out.println("Just test, param = " + invaildParam);
    }
    public Person(String name) {
        mName = name;
    }

    public void modifyName(String name) {
        modifyInnerName(name);
    }

    public String getName() {
        return mName;
    }

    public void addAddressList(String address) {
        mAddressList.add(address);
    }
    public void addInnerAddressList(String innerAddr) {
        mAddressList.add(innerAddr);
    }

    public List<String> getAllAddress() {
        return mAddressList;
    }

    public String getSchoolNo() {
        return mInnerSchoolObj.getNo();
    }

    public int getModifyInfoTimes(String info) {
        return getInnerModifyInfoTimes(info) + 2;
    }

    private int getInnerModifyInfoTimes(String info) {
        return 1;
    }
    private void modifyInnerName(String name) {
        mName = name;
    }

    public static class School {
        private String no;// 學(xué)號
        public void setNo() {
        }
        public String getNo() {
            return no;
        }
    }
}

1.1 私有變量

package com.fanff.unittestdemo.mockdemo;

import com.fanff.unittestdemo.junitdemo.Person;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.powermock.api.support.membermodification.MemberModifier;
import org.powermock.reflect.Whitebox;

import java.util.List;

public class PersonTest {

    private Person mPerson;
    @Before
    public void setUp() throws Exception {
        mPerson = new Person("Chris");
    }

    @After
    public void tearDown() throws Exception {
        mPerson =null;
    }

    /**
     * 訪問私有成員
     */
    @Test
    public void testGetPrivateMemberValue() {
        / 讀取 

        String name = Whitebox.getInternalState(mPerson, "mName");
        Assert.assertEquals("Chris", name);

        mPerson.addAddressList("Wuhan");
        mPerson.addAddressList("Shenzhen");
        List<String> list = Whitebox.getInternalState(mPerson, "mAddressList");
        Assert.assertEquals(2, list.size());
        Assert.assertEquals("Shenzhen", list.get(list.size()-1));
        / 讀取 

        / 兩種修改私有成員的方法 
        Whitebox.setInternalState(mPerson, "mName", "FanFF");
        Assert.assertEquals("FanFF", mPerson.getName());

        try {
            MemberModifier.field(Person.class, "mName").set(mPerson, "FanFF_166");
        } catch (Exception e) {
        }
        Assert.assertEquals("FanFF_166", mPerson.getName());
        / 修改 
    }
}

1.?讀取私有變量使用Whitebox.getInternalState()方法;
2. 修改私有變量,可以有如下兩種方法:
(1)?Whitebox.setInternalState()
(2)?MemberModifier.field()

1.2 私有方法

    /**
     * 訪問私有成員方法
     */
    @Test
    public void testPrivateMethod() throws Exception {
        / Verify私有方法 //
        Person personMockObj = PowerMockito.mock(Person.class);
        personMockObj.getModifyInfoTimes("school");
        PowerMockito.verifyPrivate(personMockObj, times(0)).invoke("getInnerModifyInfoTimes", anyString());

        Person personSpyObj = PowerMockito.spy(new Person("Chris"));
        personSpyObj.getModifyInfoTimes("school");
        PowerMockito.verifyPrivate(personSpyObj, times(1)).invoke("getInnerModifyInfoTimes", anyString());

        / Invoke私有方法 /
        Whitebox.invokeMethod(mPerson, "addInnerAddressList", "inner_default_addr");
        Assert.assertEquals("inner_default_addr", mPerson.getAllAddress().get(0));

        // 對私有方法進(jìn)行修改
        PowerMockito.replace(PowerMockito.method(Person.class, "modifyInnerName")).with(new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Whitebox.setInternalState(proxy, "mName", "modify name, haha");
                return null;
            }
        });
        mPerson.modifyName("FanFF_00");
        String curName = mPerson.getName();
        System.out.println("Name = " + curName);
        Assert.assertEquals("modify name, haha", curName);
    }

    /**
     * 調(diào)用私有構(gòu)造方法
     */
    @Test
    public void testPrivateConstructMethod() throws Exception {
        Person personPrivConstruct = Whitebox.invokeConstructor(Person.class, "testPrivate");
        personPrivConstruct.addAddressList("private_province");
        Assert.assertEquals("private_province", personPrivConstruct.getAllAddress().get(0));
    }

Android單元測試系列(3)-Mock之PowerMock

1. PowerMockito的Verify需要用@PrepareForTest之前已經(jīng)說過了,用到幾個(gè)類就{}包幾個(gè)類。另外注意配套使用,例如:Mockito.spy()與Mockito.verify??()配套使用,PowerMockito.spy()與PowerMockito.verifyPrivate??()配套使用;
2. 使用PowerMockito.verifyPrivate()驗(yàn)證私有方法;
3. 使用PowerMockito.replace()對私有方法進(jìn)行修改,Whitebox.invokeMethod()調(diào)用私有方法,Whitebox.invokeConstructor()調(diào)用私有構(gòu)造方法

when(), doCallRealMethod()...這些打樁方法也可以用在私有方法里去ignore一些實(shí)現(xiàn)等,這里就不詳細(xì)介紹了。

2. Final

mock對象用PowerMockito.mock()即可,其他的常用方法前面也介紹過。

3. Static

Whitebox.getInternalState()、Whitebox.invokeMethod()、PowerMockito.replace()這些方法的用法都已經(jīng)介紹過了,需要注意的是mock Static對象時(shí)使用PowerMockito.mockStatic(),驗(yàn)證靜態(tài)方法使用PowerMockito.verifyStatic()

PowerMock解決不了匿名內(nèi)部類場景,說明如下:

java - How do I use Powermockito to mock the construction of new objects when testing a method in an anonymous class? - Stack Overflow文章來源地址http://www.zghlxwxcb.cn/news/detail-401506.html

到了這里,關(guān)于Android單元測試系列(3)-Mock之PowerMock的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Springboot 如何使用Powermock做單元測試

    一、為什么要使用Mock工具 在做單元測試的時(shí)候,我們會(huì)發(fā)現(xiàn)我們要測試的方法會(huì)引用很多外部依賴的對象,比如:(發(fā)送郵件,網(wǎng)絡(luò)通訊,遠(yuǎn)程服務(wù), 文件系統(tǒng)等等)。 而我們沒法控制這些外部依賴的對象,為了解決這個(gè)問題,我們就需要用到Mock工具來模擬這些外部依賴的

    2024年02月14日
    瀏覽(20)
  • java & jacoco & powerMock 單元測試覆蓋率為0怎么解決

    我們項(xiàng)目中使用powerMock作為單元測試的mock工具,統(tǒng)計(jì)項(xiàng)目測試覆蓋率使用jacoco編譯的結(jié)果上傳到sonar,但是jacoco 和 powerMock在運(yùn)行時(shí)runtime加載代碼的時(shí)候自定義了類加載器,所以就會(huì)有沖突,導(dǎo)致測試覆蓋率為0。 使用命令 mvn clean verify sonar:sonar上傳jacoco編譯結(jié)果(這里sonar命令

    2023年04月08日
    瀏覽(26)
  • 基于Junit4+Mockito+PowerMock實(shí)現(xiàn)Controller+Service的單元測試

    基于Junit4+Mockito+PowerMock實(shí)現(xiàn)Controller+Service的單元測試

    一 導(dǎo)入的依賴 二 依賴版本 三 controller測試示例代碼 ? ? ? controller ? ? ? ? controllerTest ? ? ? ? 測試結(jié)果:覆蓋率100% ? ? ? ? 帶異常的Controller ? ? ? ? 帶異常提示的ControllerTest ? ? ? ? 測試結(jié)果,覆蓋率100% ? 三 service測試示例代碼 ? ? ? ? service ? ? ? ? serviceTest ???

    2024年02月14日
    瀏覽(28)
  • PowerMock使用-Mock私有方法

    本篇文章將說明如何使用 PowerMock 對私有方法進(jìn)行 Mock 。關(guān)于使用 PowerMock 需要引入哪些依賴,請參考PowerMock使用-依賴準(zhǔn)備。 被測試類如下所示。 被測試類中有一個(gè)公共方法 isTrue() ,在 isTrue() 方法中會(huì)調(diào)用 MockPrivateMethod 的私有方法 returnTrue() 。測試類如下所示。 Mock 私有方

    2024年02月11日
    瀏覽(15)
  • PowerMock使用-Mock靜態(tài)私有方法

    本篇文章將說明如何使用 PowerMock 對靜態(tài)私有方法進(jìn)行 Mock 。關(guān)于使用 PowerMock 需要引入哪些依賴,請參考PowerMock使用-依賴準(zhǔn)備。 被測試類如下所示。 被測試類中有一個(gè)靜態(tài)公共方法 isTrue() ,在 isTrue() 方法中會(huì)調(diào)用 MockStaticPrivateMethod 的靜態(tài)私有方法 returnTrue() 。測試程序如

    2024年02月14日
    瀏覽(18)
  • Service層代碼單元測試以及單元測試如何Mock

    Service層代碼單元測試以及單元測試如何Mock

    接著上一篇文章:單元測試入門篇,本篇文章作為單元測試的進(jìn)階篇,主要介紹如何對Springboot Service層代碼做單元測試,以及單元測試中涉及外調(diào)服務(wù)時(shí),如何通過Mock完成測試。 現(xiàn)在項(xiàng)目都流行前后端代碼分離,后端使用springboot框架,在service層編寫接口代碼實(shí)現(xiàn)邏輯。假設(shè)

    2023年04月08日
    瀏覽(18)
  • java的單元測試-mock測試

    對于普通的方法,通常采用斷言測試。 對于接口,需要使用mockMvc 對于未開發(fā)的功能,需要mockBean模擬一個(gè)業(yè)務(wù)bean java自身攜帶的工具類,也可以用于一些對拋出異常要求不高的業(yè)務(wù)或者存在全局異常的項(xiàng)目 另外有一個(gè)更加簡單的寫法,以assert開頭 曾使用注入方式得到mockM

    2023年04月08日
    瀏覽(29)
  • 單元測試與Mock

    單元測試與Mock

    作者:一笑欽陳 郵箱:xianqin_chen@163.com 你好,我是一笑欽陳,《零零后程序員成長之路》作者,一線互聯(lián)網(wǎng) Java 工程師。很高興你閱讀我的博客,讓我們共同成長進(jìn)步! 提醒:在接下來您對本博客的閱讀中,如果遇到一些內(nèi)容、圖稿、代碼等中的勘誤都可以通過郵件進(jìn)行反

    2024年02月08日
    瀏覽(46)
  • 單元測試junit+mock

    單元測試junit+mock

    單元測試(unit testing),是指對軟件中的最小可測試單元進(jìn)行檢查和驗(yàn)證。至于“單元”的大小或范圍,并沒有一個(gè)明確的標(biāo)準(zhǔn),“單元”可以是一個(gè)方法、類、功能模塊或者子系統(tǒng)。 單元測試通常和白盒測試聯(lián)系到一起 ,如果單從概念上來講兩者是有區(qū)別的,不過我們通

    2024年02月08日
    瀏覽(36)
  • Testify Mock 單元測試

    Testify 提供了單測方便的斷言能力,這里的斷言是將對代碼實(shí)際返回的斷言,代碼的實(shí)際輸出和預(yù)期是否一致。下面是 gin-gonic/gin 代碼庫的單測代碼,Testify 還提供了很多其他的方法: 單元測試中也會(huì)存在不穩(wěn)定的代碼,我們的入?yún)㈦m然保持不變,但每次單測的結(jié)果可能會(huì)發(fā)

    2024年02月03日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包