简体   繁体   English

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

[英]Mock a super class method in Mockito before spying a child class

I have a class which I need to test. 我有一堂课需要测试。

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");
    }
}

And in my test class I have a method like , 在我的测试课中,我有一个类似

@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());
}

I think I need to mock the getMyOtherClass() method in the super class, Since when executing line 1 that method gets called. 我想我需要在超类中模拟getMyOtherClass()方法,因为执行line 1会调用该方法。

how can I do that ? 我怎样才能做到这一点 ? Or what is the best way to do this ? 或最佳方法是什么?

This is purely a problem of class structure: You shouldn't need to (or want to) mock a superclass. 这纯粹是类结构的问题:您不需要(或不想)模拟超类。 When testing, you should test the entirety of your subclass (Mockz), even the parts that apply to the superclass (AnotherClass); 在测试时,您应该测试整个子类(Mockz),甚至是适用于超类的部分(AnotherClass)。 otherwise, how would you know that the subclass is fulfilling the entirety of the superclass's contract? 否则,您如何知道子类正在履行超类合同的全部内容?

If you're looking to refactor, you may consider switching to a composition/delegate pattern: 如果要重构,可以考虑切换到合成/委托模式:

public class Mockz implements AnotherInterface {
  private final AnotherClass delegate;

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

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

  // ...
}

...or consider testing a subclass of your subclass: ...或考虑测试您的子类的子类:

@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());
}

...but that second one implies that getMyOtherClass is dangerous enough to warrant mocking, which probably means it shouldn't be a part of your object's constructor code path anyway, leading to the third answer: Don't call a "heavy-lifting" method on your initialization path: ...但是第二个暗示getMyOtherClass危险到足以保证进行getMyOtherClass ,这可能意味着它无论如何都不应该成为对象的构造函数代码路径的一部分,从而导致第三个答案:不要称之为“繁重的工作”初始化路径上的“”方法:

public class Mockz extends AnotherClass{
    MyOtherClass myOtherClass;

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM