最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java單元測試Powermockito和Mockito使用總結(jié)

 更新時間:2021年09月08日 11:54:48   作者:LJWLgl  
公司單元測試框架選用了Junit 4.12,Mock框架選用了Mockito和PowerMock,本文主要介紹了Java單元測試Powermockito和Mockito使用總結(jié),感興趣的可以了解一下

最近公司在推進Java應用的單元測試,要求將單元測試的覆蓋率提高到50%以上,保證上線代碼充分自測。公司單元測試框架選用了Junit 4.12,Mock框架選用了Mockito和PowerMock,同時選用JaCoCo來做覆蓋率檢測,下面詳細介紹一下我在使用這幾個框架的一些經(jīng)驗。

依賴引入

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>2.8.9</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>1.7.4</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito2</artifactId>
    <version>1.7.4</version>
    <scope>test</scope>
</dependency>

PowerMockito的使用

Mockito、EasyMock、JMock等比較流行Mock框架有個共同的缺點,都不能mock靜態(tài)、final、私有方法等,而PowerMock可以完美解決以上框架的不足,接下來讓我們看看無所不能的PowerMock是如何解決上述問題,我們先從一個實例來看,下面的代碼是需要單測的類,被測類中既有對Spring Bean的調(diào)用,同時又包含對Redis的靜態(tài)讀取,另外還有g(shù)etInstance()單例類的使用,現(xiàn)在,我們一一來mock上述的外部類。

被單測類(主要測試queryStudentScoreByKeyword方法)

@Component
public class StudentService {

    @Resource
    private StudentDao studentDao;

    public List<StudentBo> queryStudentScoreByKeyword(String name) {
        System.out.println("invoke StudentService.queryStudentScoreByKeyword ...");

        List<StudentBo> cacheList = RedisUtils.getArray(name, StudentBo.class);
        if (CollectionUtils.isNotEmpty(cacheList)) {
            return cacheList;
        }
        String keyword = processKeyword(name);
        List<Student> students = studentDao.queryStudentByKeyWord(keyword);
        List<Integer> ids = students.stream().map(Student::getId).collect(Collectors.toList());
        List<Person> personList = SchoolManageProxy.getInstance().queryPerson(ids);

        List<StudentBo> studentBos = CommonUtils.toBo(personList, students);
        // 高亮結(jié)果
        highlightResult(studentBos, name);
        // 緩存到Redis
        RedisUtils.setArray(name, studentBos, 10 * 60);
        return studentBos;
    }

    private String processKeyword(String name) {
        System.out.println("invoke StudentService.processKeyword ...");
        String newName = name;
        // do somethings
        return newName;
    }

    private void highlightResult(List<StudentBo> result, String name) {
        System.out.println("invoke StudentService.highlightResult ...");
        // do keyword highlight
    }

}

單測類

@RunWith(PowerMockRunner.class)
@PrepareForTest({SchoolManageProxy.class, RedisUtils.class, StudentService.class})
// @PowerMockIgnore({"javax.management.*", "javax.net.ssl.*"})
@SuppressStaticInitializationFor({"cn.ganzhiqiang.ares.unittest.SchoolManageProxy"})
public class StudentServiceTest {

    @Mock
    private StudentDao mockStudentDao;

    @InjectMocks
    private StudentService studentServiceUnderTest;

    @Before
    public void setUp() {
        initMocks(this);
    }

    @Test
    public void testQueryStudentScoreByKeyword() throws Exception {
        studentServiceUnderTest = PowerMockito.spy(studentServiceUnderTest);
        PowerMockito.mockStatic(RedisUtils.class);
        PowerMockito.mockStatic(SchoolManageProxy.class);

        // mock單例調(diào)用
        SchoolManageProxy mockSchoolManageProxy = PowerMockito.mock(SchoolManageProxy.class);
        PowerMockito.when(SchoolManageProxy.getInstance()).thenReturn(mockSchoolManageProxy);
        when(mockSchoolManageProxy.queryPerson(anyList())).thenReturn(Collections.emptyList());

        // mock掉對Redis的靜態(tài)調(diào)用
        PowerMockito.when(RedisUtils.getArray(eq("tom"), eq(StudentBo.class))).thenReturn(Collections.emptyList());
        // 顯示的mock掉靜態(tài)的void的方法(可以不mock)
        PowerMockito.doNothing().when(RedisUtils.class, "setArray", anyString(), anyList(), anyInt());

        // mock私有方法processKeyword
        PowerMockito.doReturn("tom").when(studentServiceUnderTest, "processKeyword", anyString());

        // 跳過私有方法highlightResult的執(zhí)行
        PowerMockito.suppress(PowerMockito.method(StudentService.class, "highlightResult"));

        // 使用Mockito來mock服務的調(diào)用
        when(mockStudentDao.queryStudentByKeyWord(anyString())).thenReturn(Collections.emptyList());

        // Run the test
        final List<StudentBo> result = studentServiceUnderTest.queryStudentScoreByKeyword("tom");

    }
}

使用mockito來mock實例

首選我們先用Mockito來mock對Spring Bean的調(diào)用,Mockito.mock可以mock一個實例,我們這里選用@Mock注解,效果是一樣的。

// 使用Mockito來mock服務的調(diào)用 
when(mockStudentDao.queryStudentByKeyWord(anyString())).thenReturn(Collections.emptyList());

mock對Redis的靜態(tài)調(diào)用

接下來我們使用PowerMock來mock對靜態(tài)方法的調(diào)用,注意需要將RedisUtils類,加入@PrepareForTest注解中,我們既mock了getArray方法,也mock了setArray方法,其實setArray不需要mock這里顯式的mock了

PowerMockito.mockStatic(RedisUtils.class);
// mock掉對Redis的靜態(tài)調(diào)用
PowerMockito.when(RedisUtils.getArray(eq("tom"), eq(StudentBo.class))).thenReturn(Collections.emptyList());
// 顯式的mock掉靜態(tài)的void的方法(可以不mock)
PowerMockito.doNothing().when(RedisUtils.class, "setArray", anyString(), anyList(), anyInt());

mock單例類

mock單例類相對來說復雜一點,邏輯上先用Powermock mock出單例類,然后再給單例類的getInstance方法打樁,返回之前mock,再對mock類實際調(diào)用的方法打樁即可,代碼如下

PowerMockito.mockStatic(SchoolManageProxy.class);
// Powermock mock出單例類
SchoolManageProxy mockSchoolManageProxy = PowerMockito.mock(SchoolManageProxy.class);
// 給單例類的getInstance方法打樁

PowerMockito.when(SchoolManageProxy.getInstance()).thenReturn(mockSchoolManageProxy);
// 對mock類queryPerson的方法打樁
when(mockSchoolManageProxy.queryPerson(anyList())).thenReturn(Collections.emptyList());

mock私有方法

可以看到queryStudentScoreByKeyword方法調(diào)用了該類的私有方法processKeyword,如果該方法耗時過長,使用powermock也可以mock該私有方法,需要注意的studentServiceUnderTest需要用spy()來mock

// mock 實例
// spy的標準是:如果不打樁,默認執(zhí)行真實的方法,如果打樁則返回樁實現(xiàn)。
studentServiceUnderTest = PowerMockito.spy(studentServiceUnderTest);
// mock私有方法processKeyword
// doReturn(...) when(...)不做真實調(diào)用,但是when(...) thenReturn(...)還是會真實調(diào)用原方法,只是返回了指定的結(jié)果
PowerMockito.doReturn("tom").when(studentServiceUnderTest, "processKeyword", anyString());

PowerMock跳過方法執(zhí)行

使用PowerMock也可以跳過私有方法的執(zhí)行

// 跳過私有方法highlightResult的執(zhí)行
PowerMockito.suppress(PowerMockito.method(StudentService.class, "highlightResult"));

總結(jié)

筆者之前寫代碼很少會寫單測,自從公司強制要求提高單測覆蓋率之后,雖然開發(fā)效率變慢了,但是確實引起我對單測的重視,進而研究了一下PowerMockito、Mokcito等Mock框架。Powermock之所以無所不能,是因為它使用了自定義的加載器和字節(jié)碼操作技術(shù),與此同時,它還十分簡單易用,確實是個很優(yōu)秀的框架。

Demo地址:https://github.com/LJWLgl/mock-data

參考文檔

PowerMock
powermockito單元測試之深入實踐
淺談測試之PowerMock
無所不能的PowerMock,mock私有方法,靜態(tài)方法,測試私有方法,final類
Mock和Spy的區(qū)別

到此這篇關(guān)于Java單元測試Powermockito和Mockito使用總結(jié)的文章就介紹到這了,更多相關(guān)Java Powermockito和Mockito 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實現(xiàn)學生管理系統(tǒng)(IO版)

    Java實現(xiàn)學生管理系統(tǒng)(IO版)

    這篇文章主要為大家詳細介紹了Java實現(xiàn)學生管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 使用java?-jar命令啟動Spring?Boot應用時指定特定配置文件的幾種實現(xiàn)方式

    使用java?-jar命令啟動Spring?Boot應用時指定特定配置文件的幾種實現(xiàn)方式

    這篇文章主要介紹了在使用java-jar命令啟動SpringBoot應用時,指定特定配置文件的幾種方式,文中通過代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2025-01-01
  • Java中的concurrenthashmap集合詳細剖析

    Java中的concurrenthashmap集合詳細剖析

    這篇文章主要介紹了Java中的concurrenthashmap集合詳細剖析,有參構(gòu)造后第一次put時會進行初始化,由源碼可知,會先判斷所傳入的容量是否>=最大容量的一半,如果滿足條件,就會將容量修改為最大值,反之則會將容量改為所傳入數(shù)*1.5+1,需要的朋友可以參考下
    2023-11-11
  • SpringBoot實現(xiàn)讀取YML,yaml,properties文件

    SpringBoot實現(xiàn)讀取YML,yaml,properties文件

    yml,yaml,properties三種文件都是用來存放配置的文件,一些靜態(tài)數(shù)據(jù),配置的數(shù)據(jù)都會存放到里邊。本文主要為大家整理了SpringBoot實現(xiàn)讀取YML,yaml,properties文件的方法,需要的可以參考一下
    2023-04-04
  • 使用spring boot通過自定義注解打印所需日志

    使用spring boot通過自定義注解打印所需日志

    這篇文章主要介紹了使用spring boot通過自定義注解打印所需日志的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java實現(xiàn)單詞搜索迷宮游戲

    java實現(xiàn)單詞搜索迷宮游戲

    這篇文章主要介紹了java實現(xiàn)單詞搜索迷宮游戲,實例分析了迷宮游戲的實現(xiàn)技巧,需要的朋友可以參考下
    2015-05-05
  • Spring?AOP原理及動態(tài)代理

    Spring?AOP原理及動態(tài)代理

    這篇文章主要介紹了Spring?AOP原理及動態(tài)代理,文章通過圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • java實現(xiàn)登錄驗證碼

    java實現(xiàn)登錄驗證碼

    這篇文章主要為大家詳細介紹了java實現(xiàn)登錄驗證碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Java內(nèi)部類之間的閉包和回調(diào)詳解

    Java內(nèi)部類之間的閉包和回調(diào)詳解

    相信閉包和回調(diào)對每位學習Java的人來說都不陌生,那么今天小編和大家分享一篇關(guān)于Java內(nèi)部類之間的閉包和回調(diào),有需要的可以參考借鑒。
    2016-09-09
  • SpringBoot+kaptcha實現(xiàn)驗證碼花式玩法詳解

    SpringBoot+kaptcha實現(xiàn)驗證碼花式玩法詳解

    這篇文章主要想和大家聊聊kaptcha的用法,畢竟這個已經(jīng)有16年歷史的玩意還在有人用,說明它的功能還是相當強大的,感興趣的小伙伴可以了解一下
    2022-05-05

最新評論

根河市| 环江| 汝城县| 福建省| 昌吉市| 全南县| 贡嘎县| 定州市| 静乐县| 五峰| 平和县| 浦江县| 武宁县| 东至县| 桦南县| 海城市| 靖边县| 屏边| 峨边| 陆良县| 琼海市| 蒙阴县| 虎林市| 措美县| 博白县| 神农架林区| 女性| 米脂县| 克山县| 长宁县| 化德县| 玉溪市| 宝坻区| 永安市| 墨竹工卡县| 甘泉县| 宁武县| 永丰县| 永新县| 那坡县| 碌曲县|