妈蛋!空降的老大叫咱们写得代码全部都得要Mock,看来得996了~

沙海
沙海
沙海
718
文章
2
评论
2021年3月16日12:54:51
评论
4 3419字阅读11分23秒
摘要

妈蛋!空降的老大叫咱们写得代码全部都得要Mock,看来得996了~ 原创 D哥 Java面试那些事儿

妈蛋!空降的老大叫咱们写得代码全部都得要Mock,看来得996了~

原创 D哥 Java面试那些事儿

收录于话题

#Java面试那些事儿8

#程序员工具21

#Java16

最近,D哥这边新来的技术老大,要求写得所有的代码必须Mock,没有达到90%,都得要打回来~ 

说实话,咱们组之前的任务比较重,能写完代码,在加点测试用例,就很nice了,这么一搞,看来又得要开始加班搞了,谁叫咱们是苦逼的码畜,男人当牛用,女人当男人用,说到底,大多数人跟D哥一样,因为穷才做程序员。。。

妈蛋!空降的老大叫咱们写得代码全部都得要Mock,看来得996了~

说实话,D哥去查看了一下市面上的mock工具,说实话,挺多的,说白了,按照实现原理,主要分为3类:

  • 动态代理:Mockito、EasyMock、MockRunner

  • 自定义类加载器:PowerMock

  • 运行时字节码修改:JMockit、TestableMock

如下图:

妈蛋!空降的老大叫咱们写得代码全部都得要Mock,看来得996了~

动态代理:这种实现方式()只能在类的外围修修补补,不能改动类本身,因此,最安全,但功能也最弱。关于动态代理面试必问,建议多去研究一下。

自定义类加载和字节码修改:这两种方式都会修改类的字节码,前者通过完全接管类的加载过程中来实现,后者则是类加载完成后再对字节码进行“二次改造”;两者在功能上而言,差别并不大(见上图)。

因此,综合来看,阿里的 TestableMock 看起来似乎更牛逼!

使用起来真的方便,正如它官网说得“换种思路写Mock,让单元测试更简单”。

无需初始化,不挑服务框架,甭管要换的是私有方法、静态方法、构造方法还是其他任何类的任何方法,也甭管要换的对象是怎么创建的。写好Mock定义,加个@MockMethod注解,一切统统搞定。

官网源码:https://github.com/alibaba/testable-mock

官方文档:https://alibaba.github.io/testable-mock

# 实现原理

它是基于运行时修改字节码,再通过扫描测试类中是否有@MockMethod、@MockConstructor等注解修饰的方法,来判断是否要进行对应的初始化,与测试框架实现完全解藕,体验上毫无入侵感。

# 如何上手?

1、引入相关依赖

    <properties> <java.version>1.8</java.version> <testable.version>0.5.2</testable.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> <version>3.0.0-M5</version> <configuration> <argLine>@{argLine} -javaagent:${settings.localRepository}/com/alibaba/testable/testable-agent/${testable.version}/testable-agent-${testable.version}.jar</argLine> </configuration> </plugin> </plugins></build>

    2、增加一个类,调用任意方法、成员方法、静态方法,结合官方demo改动了一下,大家将就看吧,实例如下:

    DemoMock.java

      /** * 演示基本的Mock功能 * @from 公众号:Java面试那些事儿 * @author D哥 */public class DemoMock { /** * 普通方式 * @return */ public String commonFunc() { return "idea ".trim() + "." + " studycoder.com".substring(1) + "_" + "idea.studycoder.com".startsWith("ab"); } public String outerFunc(String website) { return innerFunc(staticFunc()); } /** * 静态方法 * @return */ private static String staticFunc() { return "idea_studycoder_com".replace("_","."); } /** * 内部方法 * @param website * @return */ private String innerFunc(String website) { return "our website is: " + website; }}

      DemoMockTest.java

        publicclassDemoMockTest{private DemoMock demoMock = new DemoMock();publicstaticclassMock{@MockMethod(targetClass = DemoMock.class)private String innerFunc(String text){return"mock_" + text; }@MockMethod(targetClass = DemoMock.class)private String staticFunc(){return"static"; }@MockMethod(targetClass = String.class)private String trim(){return"idea"; }@MockMethod(targetClass = String.class, targetMethod = "substring")private String sub(int i){return"sub"; }@MockMethod(targetClass = String.class)privatebooleanstartsWith(String s){returnfalse; } }@Testvoidshould_able_to_mock_common_method(){ assertEquals("idea.sub_false", demoMock.commonFunc()); verify("trim").withTimes(1); verify("sub").withTimes(1); verify("startsWith").withTimes(1); }@Testvoidshould_able_to_mock_member_method()throws Exception { assertEquals("mock_static", demoMock.outerFunc("hello")); verify("innerFunc").with("static"); verify("staticFunc").with(); }}

        # 总结

        从上面的实例中,咱们可以看出,相比其它的mock工具,阿里的TestableMock 写单元测试会方便很多,代码量也少了不少,但是也有一些缺点,比如一个方法多次调用返回不同值,需借助TestableTool.MOCK_CONTEXT,对代码来说有一定的侵入性,但总得来说,无不是一种最优的选择。

        啥也不说了,D哥决定建议团队的兄弟们用起来了~

        你们经常用哪款 mock 工具呢?欢迎在留言区告诉D哥妈蛋!空降的老大叫咱们写得代码全部都得要Mock,看来得996了~

        热门推荐:IDEA绝杀技:几分钟重构900行 "又臭又长" 的类。网友:卧槽!Google上机题:用Java代码实现哈希表。网友:太难了~Tencent Kona JDK11 来了!腾讯宣布正式开源

        继续阅读
        weinxin
        资源分享QQ群
        本站是一个IT技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
        沙海
        匿名

        发表评论

        匿名网友 填写信息

        :?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: