210805a88873b1438242844cdbc78854.png

点击上方“蓝字”关注我们

作者 | 李卓编辑 | 张婵JMockit 简介JMockit 是用以帮助开发人员编写测试程序的一组工具和 API,是一款 Java 类/接口/对象的 Mock 工具,目前广泛应用于 Java 应用程序的单元测试中。它完全基于 Java 5 SE 的 java.lang.instrument 包开发,内部使用 ASM 库来修改 Java 的 Bytecode。正是由于基于 instrument,可以修改字节码,这样便可以使得 JMockit 能够适应几乎所有的设计,所以这也是它强大的原因。 在测试单元中被调用的方法或构造函数,以及被依赖到的单元通常都是模拟的对象。Mocking 提供了一种机制,使得那些被测试的单元可以与他依赖的单元孤立开来。我们声明某个对象为  mocked类型来指定在本测试中该依赖的对象是模拟的。JMockit 可以 mock 的种类包含了:
  1. class(abstract, final, static)

  2. interface

  3. enum

  4. annotation

  5. native

JMockit 有两种 mock 的方式:
  1. Behavior-oriented(Expectations & Verifications)

  2. State-oriented(MockUp) 

通俗点讲,Behavior-oriented 是基于行为的 mock,对 mock 目标代码的行为进行模仿,更像黑盒测试。State-oriented 是基于状态的 mock,是站在目标测试代码内部的。可以对传入的参数进行检查、匹配,才返回某些结果,类似白盒。而 State-oriented 的 new MockUp 基本上可以 mock 任何代码或逻辑,非常强大。JMockit 实践使用 JMockit 首先要引用相关的 jar 包,pom 文件引用如下:
  1. org.jmockit

  2. jmockit

  3. 1.20

  4. test

  5. org.jmockit

  6. jmockit-coverage

  7. 1.20

  8. test

  9. junit

  10. junit

  11. 4.11

  12. test

  • 示例1:模拟类

被测试方法如下:

bcec3997f83b5d1ce30d3b0af0546955.png其中 NegativeTransDos 的 insert 方法是插入数据库。 为了测试 process() 方法的逻辑,希望能够模拟 dao.insert 方法的返回结果,参考测试代码如下:d8a0c89c344ece6cf254317ff1994c6a.png

可以看到使用 JMockit 基本有三个步骤:

  1. 打桩。指定要打桩类和函数,模拟返回结果。这里是 new Mockup(NegativeTransDos)。

  2. 调用被测方法。被测逻辑执行过程中,之前的打桩数据生效。

  3. 判断测试结果是否符合预期。

通过以下方法来模拟类和方法。

  1. newMockup(类){

  2. 模拟方法{

  3. 控制该方法返回结果

  4. }

  5. }

  • 示例2:模拟静态方法

被测试方法如下。其中红框是需要 Mock 的两个静态方法。通过 JMockit 模拟这两个静态方法的返回,只关注 EdaStartup 方法的自身逻辑。973a44fb27078ca57bc0ade193187601.png参考测试代码如下:32af7e81226b62646be930e44e067442.png
  • 示例3:模拟非静态方法

被测试方法:

9920af31838887260ff8ab78db15c7ca.png这里包括两种方法的模拟:McEventManager.getReceiver(),这个是静态方法调用的模拟,参考 示例1 章节。receiver.getEvent(),这个是普通对象方法调用。本节关注这种方法的模拟。 参考测试代码如下:1107310ad7fffa729ad2fd5fa94fb095.png首先需要通过 @Injectable 声明要插桩的对象:private McEventReceiver receiver; 之后使用以下方式来插桩:
  1. newNonStrictExpectations(){

  2. 要模拟的方法(参数1,参数2,…)

  3. result =返回结果

  4. }

 JMockit 提供了很彪悍的万能入参,这一点非常方便。包括:67d050c6817a2a62387cfa50ed3f076d.png
  • 示例4:模拟 private 静态方法

被测代码如下:842310f3455a74410b6190329514abf7.pngpublicMethod() 是被测试方法,其中调用了静态成员方法 privateMethod。为了摒除 privateMethod 的影响,需要模拟它的返回结果。 参考测试代码如下:03eeff4456b66c8730d5d68daecc032b.pngtest1 和 test2 的输出结果分别是:955af320450e4a2fd051965665ffbd76.png
  • 示例5:模拟 private 非静态方法

被测代码如下:8975be8017ed495e95936dd0e29c49e9.pngpublicMethod() 是被测试方法,其中调用了私有非静态成员方法 privateMethod。为了摒除 privateMethod 的影响,需要模拟它的返回结果。 参考测试代码如下:c3527db2bf6f8cc25c8515b20391b65b.png对比私有静态方法的模拟可以看到略有区别。new Expectations(XXX) 中,之前指定的是 MockClass.class,这里指定的是被测试的MockClass 对象。 test1 和 test2 的输出结果分别是:29294173f694e21cefc0a89e31aa09dc.png
  • 示例6:模拟 private 非静态成员变量

被测方法如下:512bdadf20f07a289d7ba9da52fdc85f.png其中 field 是 MockField 的私有变量。我们目的是能够模拟该私有变量的值,来关注publicMethod 方法的测试。 参考测试代码如下:7a42ae54e797f252772b482814638f09.pngtest1 和 test2 的输出结果分别是:d1949e23c8f004c96534b161df8bb6d2.png
  • 示例7:模拟 private 静态成员变量

 类似 示例6 中非静态成员变量的模拟,参考 示例4 和 示例5 的区别。示例略。 
  • 示例8:模拟类的构造函数

被测方法如下:813ed30b31cda5c87ef9344795d437b7.png为了测试异常,模拟 FileOutputStream 的构造函数,抛出 FileNotFoundException。如下:128fda201433ce194618417e25cd5bd1.png总结

本文简要介绍了 JMockit 这款广泛应用于 Java 应用程序的单元测试工具,并通过一些实践示例具体展示了模拟类、模拟静态方法、模拟非静态方法、模拟 Private 静态方法、模拟 Private 非静态方法、模拟 Private 非静态成员变量、模拟 Private 静态成员变量、模拟类的构造函数这几种情况下 JMockit 的使用方法,希望能对软件开发中的测试工作有所帮助。 6d7879e9bd90662766d4780ce529a9aa.gif d69affb9ebbf6241240e707e5c565720.gifd7633561f8938486547d9656dadfaef5.gif

猜你喜欢  

建信金科北京事业群政融支付项目组敏捷实践心得移动金融类 APP 自动化测试平台技术揭秘那些年,我在项目中遇到过的不靠谱同事政务产品如何让更多人爱用?产品信息无障碍设计初探

0931560397e156c6f0becbc827e54781.png

觉得不错,点个在看
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐