在监视子类之前,在Mockito中模拟一个超类方法

时间:2015-08-07 15:47:28

标签: java mockito

我有一个课我需要测试。

public class Mockz extends AnotherClass{
    final MyOtherClass = getMyOtherClass(); // method in AnotherClass
    Integer num = 10;
    protected void method1(){
        System.out.println("in method 1");
    }

    protected void method2(){
        System.out.println("in method 1");
    }
}

在我的测试课中,我有一个像

这样的方法
@Test
public testMethod1(){
    final Mockz mockz = Mockito.spy(new Mockz()); // line 1
    Mockito.when(mockz.method1()).thenReturn("Mocking method 1");
    System.out.println(mockz.method1());
}

我想我需要在超类中模拟getMyOtherClass()方法,因为在执行line 1时会调用该方法。

我该怎么做?或者最好的方法是什么?

1 个答案:

答案 0 :(得分:0)

这纯粹是类结构的问题:你不应该(或想要)模拟一个超类。在测试时,您应该测试整个子类(Mockz),甚至是应用于超类的部分(AnotherClass);否则,你怎么知道子类正在完成整个超类的合同?

如果您正在寻求重构,可以考虑切换到合成/委托模式:

public class Mockz implements AnotherInterface {
  private final AnotherClass delegate;

  public Mockz() { this(new AnotherClass()); }

  /** for testing */
  Mockz(AnotherClass delegate) { this.delegate = delegate; }

  // ...
}

...或考虑测试子类的子类:

@Test
public testMethod1(){
    final Mockz mockz = Mockito.spy(new Mockz() {
      @Override public OtherClass getMyOtherClass() {}
    });
    Mockito.when(mockz.method1()).thenReturn("Mocking method 1");
    System.out.println(mockz.method1());
}

...但是第二个意味着getMyOtherClass足够危险以保证模拟,这可能意味着它不应该是对象的构造函数代码路径的一部分,导致第三个答案:Don' t在初始化路径上调用“繁重”方法:

public class Mockz extends AnotherClass{
    MyOtherClass myOtherClass;

    /** Part of construction, but expensive enough to call explicitly. */
    void initializeMyOtherClass() {
        myOtherClass = getMyOtherClass();
    }
}