1. 程式人生 > >阿里 Mock 工具正式開源,幹掉市面上所有 Mock 工具!

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

最近棧長注意到阿里開源了自家的 Mock 工具:**TestableMock**,該工具號稱最輕量、簡單、舒適的 Mock 測試工具,功能十分強大,媲美 PowerMock,用法比 Mockito 還要簡潔,還不挑框架,指哪換哪,一個 @MockMethod 註解打天下。。。 這麼強大的麼?棧長趕緊來體驗一翻! ## TestableMock 簡介 TestableMock 開源地址: > https://github.com/alibaba/testable-mock ![](https://img2020.cnblogs.com/other/1218593/202101/1218593-20210127132241046-293734856.png) TestableMock 在 2020 年 12 月開始開源,出自阿里云云效團隊,主要想解決 Java 開發者在日常單元測試中經常遇到的痛點: - 外部依賴Mock繁瑣 - 私有方法難測試 - 無返回值方法難測試 - 複雜引數難構造 它所承載的職責是 “**讓Java沒有難測的方法**”,換種思路寫Mock,讓單元測試更簡單,這也是 TestableMock 名字的來歷。 無需初始化,不挑測試框架,甭管要換的是私有方法、靜態方法、構造方法還是其他任何類的任何方法,也甭管要換的物件是怎麼建立的。 寫好 Mock 定義,加個 **@MockMethod** 註解,一切統統搞定。 ## 主流Mock工具對比 在 TestableMock 開源之前,目前市面上主流的 Mock 工具主要有: - Mockito - Spock - PowerMock - JMockit - EasyMock - .... Mockito 應該是目前使用最多的 Mock 工具了,因為它使用足夠簡單,在 IntelliJ IDEA 和 Eclipse 開發工具上也都有專用的外掛支援,但 Mock 功能相對來說還是較弱,不能覆蓋所有應用場景。因為其使用的是動態代理技術,我們都知道,動態代理只能在方法前後環繞,有一定的侷限性,所以 final 型別、靜態方法、私有方法全都無法覆蓋到。 上面所列的主流的 Mock 工具也只有 PowerMock 在功能上能夠與 TestableMock 持平,但 PowerMock 使用較為複雜,而且由於使用的是自定義類載入器技術,所以也還會存在一定的問題。 **下面來看下具體對比:** | 工具 | 原理 | 最小Mock單元 | 被Mock方法限制 | 難度 | IDE支援 | | ------------ | ---------------- | ------------ | --------------------------- | ---------- | -------- | | Mockito | 動態代理 | 類 | 不能Mock私有/靜態和構造方法 | **較容易** | **很好** | | Spock | 動態代理 | 類 | 不能Mock私有/靜態和構造方法 | 較複雜 | 一般 | | PowerMock | 自定義類載入器 | 類 | **任何方法皆可** | 較複雜 | **較好** | | JMockit | 執行時位元組碼修改 | 類 | 不能Mock構造方法 | 較複雜 | 一般 | | TestableMock | 執行時位元組碼修改 | 方法 | **任何方法皆可** | **很容易** | 一般 | TestableMock 和 JMockit 底層一致,使用的是 "**執行時位元組碼修改**" 技術,在單元測試啟動時就掃描測試類和被測類的位元組碼,完成 Mock 方法的替換。 現在綜合看來,阿里開源的 TestableMock 是最牛逼的了,這是要幹掉市面上所有 Mock 工具!另外,關注公眾號Java技術棧,在後臺回覆:工具,可以獲取我整理的 Java 開發工具系列乾貨,非常齊全。 ## 上手 TestableMock 在專案中的 pom.xml 檔案中增加 testable 相關依賴及單元測試相關依賴和外掛,完整的配置如下: ``` ``` 這裡棧長以 Maven 為示例整合使用 TestableMock,Gradle 版本請參考官方文件。另外,關注公眾號Java技術棧,在後臺回覆:Maven,可以獲取我整理的 Maven 系列教程,非常齊全。 增加一個類,呼叫任意方法、成員方法、靜態方法: ``` /** * @from 公眾號:Java技術棧 * @author 棧長 */ public class TestableMock { /** * 呼叫任意方法 */ public String commonMethod() { return " www ".trim() + "." + " javastack".substring(1) + "www.javastack.cn".startsWith(".com"); } /** * 呼叫成員、靜態方法 */ 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技術棧 */ 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 靜態方法 * @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 註解標識的方法都是 Mock 方法,Mock 了任意方法、成員方法、靜態方法。 使用確實很簡單,非常靈活,功能也確實比動態代理那種要強大,一個 @MockMethod 註解走天下,可以扔掉其他的 Mock 工具了。 參考文件: - https://github.com/alibaba/testable-mock - https://alibaba.github.io/testable-mock/ > 版權申明:本文系公眾號 "Java技術棧" 原創,原創實屬不易,轉載、引用本文內容請註明出處,禁止抄襲、洗稿,請自重,尊重他人勞動成果和智慧財產權。 **近期熱文推薦:** 1.[Java 15 正式釋出, 14 個新特性,重新整理你的認知!!](http://www.javastack.cn/article/2020/java15-released/) 2.[終於靠開源專案弄到 IntelliJ IDEA 啟用碼了,真香!](http://www.javastack.cn/article/2020/intellij-idea-by-open-source-project/) 3.[我用 Java 8 寫了一段邏輯,同事直呼看不懂,你試試看。。](http://www.javastack.cn/article/2020/java-8-optional-map-do-you-know/) 4.[吊打 Tomcat ,Undertow 效能很炸!!](http://www.javastack.cn/article/2020/undertow-introduce-with-spring-boot/) 5.[《Java開發手冊(嵩山版)》最新發布,速速下載!](http://www.javastack.cn/article/2020/alibaba-release-java-develop-rules-songshan/) 覺得不錯,別忘了隨手點贊+轉發哦!