下图为jmockit 类图。在我们编写代码时几乎都会用到Expectations(期望)和Verifications(校验),二者均继承自Invacations.

常会用到的注解有:@Mocked @Tested @Injectable(@Tested和@Injectable经常配对使用),@Capturing(用于接口)

jmockit学习

mock类型和实例

从依赖的测试代码调用的方法和构造函数是mock(模拟)的目标。 Mocking提供了我们需要的机制,以便将被测试的代码与(一些)依赖关系隔离开来。我们通过声明适当的模拟字段和/或模拟参数来指定要为给定测试(或多个测试)模拟哪些特定依赖性; mock字段声明为测试类的注释实例字段,而mock参数声明为测试方法的注释参数。 要模拟的依赖关系的类型将是模拟字段或参数的类型。这种类型可以是任何类型的引用类型:接口,类(包括抽象和final类型),注释或枚举。

默认情况下,mock类型的所有非私有方法(包括静态,final或native的任何方法)将在测试期间被模拟。如果声明的mocked类型是一个类,那么所有的超类直到但不包括java.lang.Object也将被递归地mock。同时,继承的方法也会自动被mock。在一个类的情况下,它的所有非私有构造函数将被mock。

当一个方法或构造器被mock时,它的原始实现代码将不会被执行在测试期间发生的调用。相反,调用将被重定向到JMockit,所以它可以以显式或隐式指定测试方式处理。

以下示例测试框架用作对mock字段和mock参数的声明以及它们在测试代码中通常使用的方式的基本说明。

对于在测试方法中声明的mock参数,声明类型的实例将由JMockit自动创建,并在JUnit / TestNG测试运行器执行测试方法时传递; 因此,参数值永远不会为null。对于mock属性,声明类型的实例将由JMockit自动创建并分配给字段,前提是它不是final(final不允许继承)。

有一些不同的注解可用于声明模拟属性和参数,以及默认模拟行为可以修改以适应特定测试的需要的方式。本章的其他部分详细介绍,但基本是:@Mocked是中央模拟注解,有一个可选的属性,在某些情况下是有用的; @Injectable是另一个模拟注释,它限制mock单个模拟实例的实例方法;@Capturing是另一个模拟注释,它扩展mock到实现模拟接口的类,或扩展mock类的子类。当@Injectable或@Capturing应用于模拟字段或模拟参数时,隐含了@Mocked,所以它不需要(但可以)应用。由JMockit创建的模拟实例可以在测试代码(用于期望的记录和验证)中正常使用,和/或传递到测试中的代码。或者他们可能只是闲置。与其他模拟API不同,这些模拟对象不一定是被测试代码在其依赖项上调用实例方法时使用的对象。默认情况下(即,当不使用@Injectable时),JMockit不关心调用模拟实例方法的对象。这允许直接在测试下的代码中创建的实例的透明模拟,当所述代码使用新运算符调用全新实例上的构造函数时;实例化的类必须由测试代码中声明的模拟类型覆盖,这就是全部。

Expectations

期望表示对与给定测试相关的特定模拟方法/构造函数的调用的集合。期望可以覆盖对同一方法或构造器的多个不同调用,但是它不必覆盖在测试的执行期间发生的所有这样的调用。特定调用是否与给定期望匹配将不仅取决于方法/构造函数签名,而且还取决于诸如调用该方法的实例,参数值和/或已经匹配的调用的数量的运行时方面。因此,可以(可选地)为给定期望指定几种类型的匹配约束。

当我们具有一个或多个调用参数时,可以为每个参数指定确切的参数值。例如,可以为String参数指定值“test string”,从而导致期望仅在相应参数中将这些调用与此精确值进行匹配。正如我们将在后面看到的,我们可以指定更宽松的约束,而不是指定精确的参数值,它将匹配整组不同的参数值。

下面的示例显示了Dependency#someMethod(int,String)的期望,它将使用指定的确切参数值匹配此方法的调用。注意,期望本身是通过对模拟方法的单独调用来指定的。没有涉及特殊的API方法,这在其他mocking API中是常见的。然而,这种调用不算作我们对测试感兴趣的“真正的”调用之一。它只在那里,以便可以指定期望。

 

 1 @Test
 2     public void doBusinessOperationXyz(@Mocked final Dependency mockInstanc){
 3     ... ...    
 4         new Expectations(){{
 5         ... ...       
 6             //实例方法的期望:       
 7             //mockInstance.someMethod(1,“test”); 
 8             result =“mocked”;       
 9         ... ...    
10     }};    
11     //这里调用被测代码,导致模拟调用可能或可能不匹配指定的期望。
12 }}
View Code

 在我们了解记录,重放和验证调用之间的差异后,我们将更多地了解期望。

record-replay-verify模型

任何开发人员测试都可以分为至少三个单独的执行阶段。 这些阶段按顺序执行,一次一个,如下所示。

 1 @Test
 2     public void someTestMethod(){
 3     //1.准备:在被测试代码可以执行之前的任何需要。
 4     ... ...    
 5     // 2.通过调用public方法来执行测试下的代码。    
 6     ... ...    
 7     // 3.验证:无论需要检查以确保代码行使    
 8     //     测试完成了它的工作。    
 9     ... ...
10 }}
View Code

相关文章:

  • 2021-08-03
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-07-04
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-10-27
  • 2021-10-31
  • 2021-05-30
  • 2022-12-23
  • 2021-07-14
  • 2021-07-28
相关资源
相似解决方案