<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          阿里 Mock 工具正式開源,干掉市面上所有 Mock 工具!

          共 4634字,需瀏覽 10分鐘

           ·

          2021-01-28 11:13

          Java技術(shù)棧

          www.javastack.cn

          關(guān)注閱讀更多優(yōu)質(zhì)文章



          最近棧長注意到阿里開源了自家的 Mock 工具:TestableMock,該工具號稱最輕量、簡單、舒適的 Mock 測試工具,功能十分強大,媲美 PowerMock,用法比 Mockito 還要簡潔,還不挑框架,指哪換哪,一個 @MockMethod 注解打天下。。。

          這么強大的么?棧長趕緊來體驗一翻!

          TestableMock 簡介

          TestableMock 開源地址:

          https://github.com/alibaba/testable-mock

          TestableMock 在 2020 年 12 月開始開源,出自阿里云云效團隊,主要想解決 Java 開發(fā)者在日常單元測試中經(jīng)常遇到的痛點:

          • 外部依賴Mock繁瑣
          • 私有方法難測試
          • 無返回值方法難測試
          • 復(fù)雜參數(shù)難構(gòu)造

          它所承載的職責(zé)是 “讓Java沒有難測的方法”,換種思路寫Mock,讓單元測試更簡單,這也是 TestableMock 名字的來歷。

          無需初始化,不挑測試框架,甭管要換的是私有方法、靜態(tài)方法、構(gòu)造方法還是其他任何類的任何方法,也甭管要換的對象是怎么創(chuàng)建的。

          寫好 Mock 定義,加個 @MockMethod 注解,一切統(tǒng)統(tǒng)搞定。

          主流Mock工具對比

          在 TestableMock 開源之前,目前市面上主流的 Mock 工具主要有:

          • Mockito
          • Spock
          • PowerMock
          • JMockit
          • EasyMock
          • ....

          Mockito 應(yīng)該是目前使用最多的 Mock 工具了,因為它使用足夠簡單,在 IntelliJ IDEA 和 Eclipse 開發(fā)工具上也都有專用的插件支持,但 Mock 功能相對來說還是較弱,不能覆蓋所有應(yīng)用場景。因為其使用的是動態(tài)代理技術(shù),我們都知道,動態(tài)代理只能在方法前后環(huán)繞,有一定的局限性,所以 final 類型、靜態(tài)方法、私有方法全都無法覆蓋到。

          上面所列的主流的 Mock 工具也只有 PowerMock 在功能上能夠與 TestableMock 持平,但 PowerMock 使用較為復(fù)雜,而且由于使用的是自定義類加載器技術(shù),所以也還會存在一定的問題。

          下面來看下具體對比:

          工具原理最小Mock單元被Mock方法限制難度IDE支持
          Mockito動態(tài)代理不能Mock私有/靜態(tài)和構(gòu)造方法較容易很好
          Spock動態(tài)代理不能Mock私有/靜態(tài)和構(gòu)造方法較復(fù)雜一般
          PowerMock自定義類加載器任何方法皆可較復(fù)雜較好
          JMockit運行時字節(jié)碼修改不能Mock構(gòu)造方法較復(fù)雜一般
          TestableMock運行時字節(jié)碼修改方法任何方法皆可很容易一般

          TestableMock 和 JMockit 底層一致,使用的是 "運行時字節(jié)碼修改" 技術(shù),在單元測試啟動時就掃描測試類和被測類的字節(jié)碼,完成 Mock 方法的替換。

          現(xiàn)在綜合看來,阿里開源的 TestableMock 是最牛逼的了,這是要干掉市面上所有 Mock 工具!另外,關(guān)注公眾號Java技術(shù)棧,在后臺回復(fù):工具,可以獲取我整理的 Java 開發(fā)工具系列干貨,非常齊全。

          上手 TestableMock

          在項目中的 pom.xml 文件中增加 testable 相關(guān)依賴及單元測試相關(guān)依賴和插件,完整的配置如下:


          ????0.4.9
          ????5.6.2



          ????
          ????????com.alibaba.testable
          ????????testable-all
          ????????${testable.version}
          ????????test
          ????

          ????
          ????????org.junit.jupiter
          ????????junit-jupiter-api
          ????????${junit.version}
          ????????test
          ????




          ????
          ????????
          ????????????org.apache.maven.plugins
          ????????????maven-surefire-plugin
          ????????????
          ????????????????-javaagent:${settings.localRepository}/com/alibaba/testable/testable-agent/${testable.version}/testable-agent-${testable.version}.jar
          ????????????

          ????????

          ????


          這里棧長以 Maven 為示例集成使用 TestableMock,Gradle 版本請參考官方文檔。另外,關(guān)注公眾號Java技術(shù)棧,在后臺回復(fù):Maven,可以獲取我整理的 Maven 系列教程,非常齊全。

          增加一個類,調(diào)用任意方法、成員方法、靜態(tài)方法:

          /**
          ?*?@from 公眾號:Java技術(shù)棧
          ?*?@author?棧長
          ?*/
          public?class?TestableMock?{

          ????/**
          ?????*?調(diào)用任意方法
          ?????*/
          ????public?String?commonMethod()?{
          ????????return?"?www?".trim()?+?"."?+?"?javastack".substring(1)?+?"www.javastack.cn".startsWith(".com");
          ????}


          ????/**
          ?????*?調(diào)用成員、靜態(tài)方法
          ?????*/
          ????public?String?memberMethod(String?s)?{
          ????????return?"{?\"result\":?\""?+?innerMethod(s)?+?staticMethod()?+?"\"}";
          ????}

          ????private?static?String?staticMethod()?{
          ????????return?"WWW_JAVASTACK_CN";
          ????}

          ????private?String?innerMethod(String?website)?{
          ????????return?"our?website?is:?"?+?website;
          ????}


          }

          增加單元測試類:

          import?com.alibaba.testable.core.annotation.MockMethod;
          import?org.junit.jupiter.api.Test;

          import?static?com.alibaba.testable.core.matcher.InvokeVerifier.verify;
          import?static?org.junit.jupiter.api.Assertions.assertEquals;

          /**
          ?*?@author?棧長
          ?*?@from 公眾號:Java技術(shù)棧
          ?*/
          class?TestableMockTest?{

          ????private?TestableMock?testableMock?=?new?TestableMock();

          ????/**
          ?????*?Mock?任意方法
          ?????*?@return
          ?????*/
          ????@MockMethod(targetClass?=?String.class)
          ????private?String?trim()?{
          ????????return?"http://www";
          ????}

          ????@MockMethod(targetClass?=?String.class,?targetMethod?=?"substring")
          ????private?String?substr(int?i)?{
          ????????return?"javastack.cn_";
          ????}

          ????@MockMethod(targetClass?=?String.class)
          ????private?boolean?startsWith(String?website)?{
          ????????return?false;
          ????}

          ????/**
          ?????*?Mock?成員方法
          ?????*?@param?text
          ?????*?@return
          ?????*/
          ????@MockMethod(targetClass?=?TestableMock.class)
          ????private?String?innerMethod(String?text)?{
          ????????return?"mock_"?+?text;
          ????}

          ????/**
          ?????*?Mock?靜態(tài)方法
          ?????*?@return
          ?????*/
          ????@MockMethod(targetClass?=?TestableMock.class)
          ????private?String?staticMethod()?{
          ????????return?"_MOCK_JAVASTACK";
          ????}

          ????@Test
          ????void?commonMethodTest()?{
          ????????assertEquals("http://www.javastack.cn_false",?testableMock.commonMethod());
          ????????verify("trim").withTimes(1);
          ????????verify("substr").withTimes(1);
          ????????verify("startsWith").withTimes(1);
          ????}

          ????@Test
          ????void?memberMethodTest()?{
          ????????assertEquals("{?\"result\":?\"mock_hello_MOCK_JAVASTACK\"}",?testableMock.memberMethod("hello"));
          ????????verify("innerMethod").withTimes(1);
          ????????verify("staticMethod").withTimes(1);
          ????????verify("innerMethod").with("hello");
          ????????verify("staticMethod").with();
          ????}
          ????
          }

          在以上單元測試類中,以 ?@MockMethod 注解標(biāo)識的方法都是 Mock 方法,Mock 了任意方法、成員方法、靜態(tài)方法。

          使用確實很簡單,非常靈活,功能也確實比動態(tài)代理那種要強大,一個 @MockMethod 注解走天下,可以扔掉其他的 Mock 工具了。

          參考文檔:

          • https://github.com/alibaba/testable-mock
          • https://alibaba.github.io/testable-mock/

          版權(quán)申明:本文系公眾號 "Java技術(shù)棧" 原創(chuàng),原創(chuàng)實屬不易,轉(zhuǎn)載、引用本文內(nèi)容請注明出處,禁止抄襲、洗稿,請自重,尊重他人勞動成果和知識產(chǎn)權(quán)。






          關(guān)注Java技術(shù)??锤喔韶?/strong>



          戳原文,獲取精選面試題!
          瀏覽 35
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久操影视 | 欧美A∨在线 | 狼人永久地址在线观看高清无码 | 成人黄色在线观看视频 | 寡妇天天射天天日 |