乐趣区

关于java:阿里-Mock-工具正式开源干掉市面上所有-Mock-工具

最近栈长留神到阿里开源了自家的 Mock 工具:TestableMock,该工具号称最轻量、简略、舒服的 Mock 测试工具,性能非常弱小,媲美 PowerMock,用法比 Mockito 还要简洁,还不挑框架,指哪换哪,一个 @MockMethod 注解打天下。。。

这么弱小的么?栈长连忙来体验一翻!

TestableMock 简介

TestableMock 开源地址:

https://github.com/alibaba/te…

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 相干依赖及单元测试相干依赖和插件,残缺的配置如下:

<properties>
    <testable.version>0.4.9</testable.version>
    <junit.version>5.6.2</junit.version>
</properties>

<dependencies>
    <dependency>
        <groupId>com.alibaba.testable</groupId>
        <artifactId>testable-all</artifactId>
        <version>${testable.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <argLine>-javaagent:${settings.localRepository}/com/alibaba/testable/testable-agent/${testable.version}/testable-agent-${testable.version}.jar</argLine>
            </configuration>
        </plugin>
    </plugins>
</build>

这里栈长以 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/te…
  • https://alibaba.github.io/tes…

版权申明:本文系公众号 “Java 技术栈 ” 原创,原创实属不易,转载、援用本文内容请注明出处,禁止剽窃、洗稿,请自重,尊重别人劳动成果和知识产权。

近期热文举荐:

1.Java 15 正式公布,14 个新个性,刷新你的认知!!

2. 终于靠开源我的项目弄到 IntelliJ IDEA 激活码了,真香!

3. 我用 Java 8 写了一段逻辑,共事直呼看不懂,你试试看。。

4. 吊打 Tomcat,Undertow 性能很炸!!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

退出移动版