![](/img/trans.png)
[英]How can I mock an instance of an enum class with PowerMock & 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.