繁体   English   中英

使用 Mockito,如何在没有该类的实例的情况下模拟实例方法的返回值?

[英]Using Mockito, how can I mock a return value of an instance method without having an instance of that class?

我有一个名为MyClass的类。 我在那个类中有一个方法, public int getSpacing()

我正在测试来自不同类的方法。 public static ArrayList<SpecialObject> getSpecialObjects()

getSpecialObjects()MyClass的实例上调用getSpacing() 当我使用 Mockito 运行测试时,我希望此方法始终返回 0。 我怎样才能做到这一点? 我发现的所有示例都需要一个对象的特定实例,然后才能模拟方法。

这是我知道该怎么做的。

MyClass myInstance = new MyClass();        
Mockito.when(myInstance.getSpacing()).thenReturn(0);

但是,我想为MyClass所有实例覆盖getSpacing()的行为,因为这些实例是在getSpecialObjects()动态创建的。 我怎样才能做到这一点?

这就是我想说的,但不知道怎么说。

Mockito.when((Any instance of MyClass).getSpacing()).thenReturn(0);

您可以使用 powermock 模拟MyClass构造函数,如下所示:

MyClass myClassSpy = spy(new MyClass());
whenNew(MyClass.class).withAnyArguments().thenReturn(myclassSpy);

然后,您可以使用通常的 spy 覆盖从该方法返回任何您喜欢的内容。 不要忘记PrepareForTest MyClass

你不能像你描述的那样纯粹在 Mockito 中做到这一点。 Mockito 不控制 MyClass 类型的所有对象,而是使创建和实例化它可以控制的代理子类变得非常容易。 这就是为什么 Mockito 依赖于非 final 的类和方法,以及为什么你不能使用 Mockito 来影响所有实例的行为。

另请参阅:当我们无法将模拟对象传递给类的实例时如何使用 Mockito

一种解决方法是切换库:正如 Slava 所描述的,您可以使用 PowerMock,它有一个自定义类加载器,可以修改字节码,其中包括替换对new MyClass()构造函数的调用,以便它们可以返回您的模拟。

作为替代方案,您可以重组您的类以使其更易于测试。 您可以完全构建依赖注入的类并注入Provider<MyClass> ,但有一个更本地化的解决方案,具有大部分好处:

public class ClassThatConsumesMyClass {
  /** Visible for testing. Override to customize MyClass instances. */
  MyClass createMyClass() {
    return new MyClass();
  }

  public ReturnValue getSpecialObjects(int n) {
    for (int i = 0; i < n; i++) {
      // Instead of calling "new MyClass()", call your method.
      MyClass myClassInstance = createMyClass();
      // ...
    }
    // ...
  }
}

public class TestForClassThatConsumesMyClass {
  ClassThatConsumesMyClass consumer;

  @Before public void createMyClass() {
    consumer = new ClassThatConsumesMyClass() {
      @Override MyClass createMyClass() {
        MyClass myInstance = Mockito.mock(MyClass.class);
        Mockito.when(myInstance.getSpacing()).thenReturn(0);
        return myInstance;
      }
    }
  }

  // Test as usual, now that you've mocked every newly-created
  // instance of MyClass in your consumer.
}

暂无
暂无

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

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