JMockit 如何 Mock 部分方法/属性

现在的 JMockit 已经偷偷升级到了 1.23 版了,在 JVM 上的 Mock 工具中就数它最无敌了,因为它抢夺了最佳控制点  --javaagent,可以说它是无所不能的。一般我们使用 JMockit 是通过两种方式,new MockUpnew Expectations. JMock 不仅能够 Mock 类的所有方法,还能部分 Mock -- 这个是 new Expectations 的默认行为。所以这里我们来看下在使用 new Expectations 的情况下如何对类的部份静态方法或部分实例方法进行 Mock。

大致表述一下,共分为三种情况

  1. 针对类进行 Mock, 只有录制的静态方法被 Mock 住,其他的静态方法或实例方法都会调用实际实现
  2. 针对某一实例进行 Mock,只在调用该实例已录制的方法才被 Mock 住,静态方法或新建实例调用任何方法都是实际实现
  3. 针对类进行 Mock,但录制的是一个实例方法,那么该实例或任何新建实例在调用该录制方法时都会被 Mock 住

不知道上面在说什么,本来就是空洞无凭,所以还是下实例,假定要测试下面这个类,或者说是测试使用到下面类的其他类

class ClassToBeMocked {
  public static String f1(){
    return "f1";
  }
  public static String f2() {
    return "f2";
  }
 
  public String f3() {
    return "f3";
  }
 
  public String f4() {
    return "f4";
  }
}

然后分三个测试用例来各自说明

一: 针对类,Mock 了一个静态方法

@Test
public void testPartialMockingStaticMethods() {
  new Expectations(ClassToBeMocked.class) {{
    ClassToBeMocked.f1();  //只有该静态 f1() 方法受影响
    result = "mocked";
  }};
 
  //mocked
  assertEquals("mocked", ClassToBeMocked.f1());
   
  assertEquals("f2", ClassToBeMocked.f2());
  assertEquals("f3", new ClassToBeMocked().f3());
}

Mock  了一个静态方法 f1(), 只有调用该方法时才使用 Mock 的结果,其他的静态或实例方法都不受影响,会调用实际的实现。

二:针对某一实例,Mock  了一个实例方法

@Test
public void testPartialMockingInstanceMethods() {
  final ClassToBeMocked mockedInstance = new ClassToBeMocked();
  new Expectations(mockedInstance) {{
    mockedInstance.f3(); //只有该实例的 f3() 方法受影响
    result = "mocked";
  }};
 
  //mocked
  assertEquals("mocked", mockedInstance.f3());
 
  assertEquals("f3", new ClassToBeMocked().f3());
  assertEquals("f1", ClassToBeMocked.f1());
  assertEquals("f4", mockedInstance.f4());
}

只有调用该实例的 f3() 方法才使用 Mock 的结果,其他不管是调用别的实例的  f3() 还是别的方法,或任何静态方法都不受影响。

三:针对类,Mock 了一个具体实例的方法

@Test
public void testPartialMockingInstanceMethodsWithClass() {
  ClassToBeMocked anotherInstance = new ClassToBeMocked();

  final ClassToBeMocked mockedInstance = new ClassToBeMocked();
    new Expectations(ClassToBeMocked.class) {{
    mockedInstance.f3();  //任何 ClassToBeMocked 实例都受到影响,也包括上面的 anotherInstance
    result = "mocked";
  }};
 
  //mocked
  assertEquals("mocked", mockedInstance.f3());
  assertEquals("mocked", anotherInstance.f3());
  assertEquals("mocked", new ClassToBeMocked().f3());
 
  assertEquals("f1", ClassToBeMocked.f1());
  assertEquals("f4", mockedInstance.f4());
}

new Expectations(ClassToBeMocked.class) 是一个类,但 Mock 是一个具体实例的 f3() 方法,结果是任何访类的实例(无论何时创建的) 方法 f3() 都被 Mock 住。其他的实例或静态方法不受影响。官方的解释是如果是一个类出现在 Expectations 的参数中,就相当于该类的构造方法被 Mock 住,由此生成的实例的被录制方法都将被波及。

至于属性的 Mock, 它与方法的 Mock 是一致的,原本在 Scala 中方法和属性就不再分得那么清楚。

参考: 1. Partial Mocking

类别: Java/JEE. 标签: , . 阅读(155). 订阅评论. TrackBack.

Leave a Reply

Be the First to Comment!

avatar
wpDiscuz