青年IT男

个人从事金融行业,就职过易极付、思建科技等重庆一流技术团队,目前就职于某网约车平台负责整个支付系统建设。自身对金融行业有强烈的爱好。同时也实践大数据、数据存储、自动化集成和部署、分布式微服务、人工智能等领域。

JMockit原理剖析 -JMockit架构

JMockit原理剖析 -JMockit架构

JMockit的功能确实太强了,作为一名程序员,我们还是需要知其然知其所以然以探究技术的本质。看看它背后是如何工作的。

在弄懂JMockit的原理之前,我们先对JMockit的总体有个初步的认识。看看JMockit里面的都有些什么东东。

通过上面的架构图,我们可以看到JMockit有如下核心组件

JVM Attach

JMockit使用了JDK6动态添加代理功能。目的是为了运行JMockit启动程序做准备。 JMockit提供了不同OS的hotSpot JVM的Attach支持: BsdVirtualMachine, LinuxVirtualMachine,SolarisVirtualMachine,WindowsVirtualMachine。

JMockit启动程序:主要功能是集成测试框架(JUnit/TestNG),完成对JMockit类转换器织入。

测试框架集成

提供了JUnit4/5, TestNG的支持。

a)对JUnit4的集成方法:改写JUnit4的核心类org.junit.runner.Runner,org.junit.runners.model.FrameworkMethod, org.junit.runners.model.TestRunnerDecorator,org.junit.runners.model.RunNotifier。改写的目的是为了让测试程序在运行测试方法前,完成Mock 注解API(@Mocked,@Injectable,@Capturing)修饰的测试属性&测试参数的类做相关字节码的织入。
详见可以见JMockit源代码中Runner类,FakeFrameworkMethod类,JUnit4TestRunnerDecorator类,RunNotifierDecorator类。

b)对JUnit5/TestNG的集成方法: 由于JUnit5/TestNG支持ServiceLoader的扩展体系,JMockit通过配置/META-INF/services/org.junit.platform.engine.TestEngine,/META-INF/services/org.testng.ITestNGListener完成对JUnit5/TestNG的集成。集成的目的同样是为了让测试程序在运行测试方法前,完成Mock 注解API(@Mocked,@Injectable,@Capturing)修饰的测试属性&测试参数的类做相关字节码的织入。

字节码处理
通过ASM,在类的某个方法中加入某段逻辑以达到Mock的目的;生成某个类的子类以支持抽象类的Mock;生成某个接口的实例类以支持接口的Mock。通过ASM, 这些都变得不那么复杂了。

类转换器
类转换器是JMockit的核心。Mock的核心就是JMockit不同的类转换器在起作用。

a)录制(ExpectationsTransformer)

用于对new Expectations(){{}},new Verifications(){{}},匿名类进行重定义。用于支持测试程序中的录制,重放,校验。

b)伪类(ClassLoadingBridgeFields)
伪类,即new MockUp {}的匿名类或 extends MockUp的子类。
用于伪类的@Mock方法提供支持。 通过识别伪类@Mock方法,在对应的方法体中织入一段分支,用于走伪类的@Mock方法逻辑。

c)覆盖率(CodeCoverage)
用于支持JMockit Coverage功能。 通过在类的方法体行加埋点。即可以完成行覆盖率,路径覆盖率的计算。

d)类缓存(CachedClassfiles)

这个没有什么好说的,对类进行了重定义,当然要求一个测试方法结束后,能复原类的原有字节码,于是需要一个Cache了。

e)对象捕捉(CaptureTransformer)

用于支持JMockit的withCapture()功能,即捕捉某次测试中,某个类的某个方法的入参是什么,并记录下来。通常用于在验证代码块中,某个方法的入参是否符合期望。

Mock API

@Mocked, @Tested ,@Injectable, @Capturing, MockUp, @Mock ,Expectations, Verifications这些API,通过前面基础知识,常见用法等的学习,这些API已经耳熟能详了吧。 基本能满足大部分的Mock场景了。

0
1028826685@qq.com