[英]Mocking an abstract method, but not the class constructor
我有一个场景,其中有一个类似于以下内容的抽象类。 我想模拟通过构造函数提供的RandomNumberGenerator
实例,并且想编写一个单元测试来测试doSomethingRandomLotsOfTimes
方法中的逻辑。
有没有办法我可以通过模仿/另一个框架做到这一点?
public abstract class MyClass {
private final RandomNumberGenerator randomNumberGenerator;
public MyClass(RandomNumberGenerator randomNumberGenerator) {
this.randomNumberGenerator = randomNumberGenerator;
}
public abstract void doSomething(int x);
public void doSomethingRandomLotsOfTimes() {
for(int i=0; i<10; i++) {
int r = randomNumberGenerator.next();
doSomething(r);
}
}
}
我的测试
@Test
public void testItDoesSomething10Times() {
// Given
when(randomNumberGenerator.next()).thenReturn(0);
MyClass myClass = ...
// When
myClass.doSomethingRandomLotsOfTimes();
// Then
// Assert Something
}
您的班级很容易通过组合实现:
public final class MyClass {
private final RandomNumberGenerator randomNumberGenerator;
private final IntConsumer somethingDoer;
public MyClass(
RandomNumberGenerator randomNumberGenerator,
IntConsumer somethingDoer) {
this.randomNumberGenerator = randomNumberGenerator;
this.somethingDoer = somethingDoer;
}
public void doSomethingRandomLotsOfTimes() {
for(int i=0; i<10; i++) {
int r = randomNumberGenerator.next();
somethingDoer.consume(r);
}
}
}
现在,您可以编写一个单元测试来断言MyClass
有效的,并且它将对somethingDoer
调用预期的次数; 并且您可以编写单元测试来断言IntConsumer
的工作。
但是您不必担心诸如此类的事情:
MyClass
粗心/恶意实现从doSomething()
调用doSomethingRandomLotsOfTimes()
(嗯,也许您这样做,要困难得多...) 等等
无法直接实例化抽象类。 您必须实例化扩展抽象类的非抽象类。
声明一个非抽象类,该类在单元测试类中扩展抽象类(例如, public static class blam extends MyClass
),并提供所有抽象方法的空实现。
一旦有了可以实例化的类,就可以创建RandomNumberGenerator类的间谍。 间谍程序可以让您测试间谍程序中的方法是否被调用。
创建一个blam
实例,并将间谍RandomNumberGenerator传递为构造函数参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.