当前位置: 代码迷 >> java >> 在监视子类之前在Mockito中模拟超级类方法
  详细解决方案

在监视子类之前在Mockito中模拟超级类方法

热度:60   发布时间:2023-07-25 19:50:24.0

我有一堂课需要测试。

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会调用该方法。

我怎样才能做到这一点 ? 或最佳方法是什么?

这纯粹是类结构的问题:您不需要(或不想)模拟超类。 在测试时,您应该测试整个子类(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危险到足以保证进行getMyOtherClass ,这可能意味着它无论如何都不应该成为对象的构造函数代码路径的一部分,从而导致第三个答案:不要称之为“繁重的工作”初始化路径上的“”方法:

public class Mockz extends AnotherClass{
    MyOtherClass myOtherClass;

    /** Part of construction, but expensive enough to call explicitly. */
    void initializeMyOtherClass() {
        myOtherClass = getMyOtherClass();
    }
}
  相关解决方案