我正在尝试对以下ClassA(String)
类的ClassA
构造函数进行单元测试:
import ExternalObject;
class ClassA{
private ExternalObject externalObject;
public ClassA() {
super();
}
public ClassA(String string) {
super();
this.externalObject = new ExternalObject().parseString(string);
}
}
我想模拟
new ExternalObject().parseString(string)
调用并使用示例ExternalObject
对象对其进行存根。我已经研究了Mockito,但是看来Mockito无法完成此任务,因为:
Mockito只能模拟方法,而不能模拟方法中的语句。
Mockito要求在模拟对象之前先创建对象。 Mockito needs an instance of the class before you can begin mocking。因此,即使我将
new ExternalObject().parseString()
调用放在ClassA类的单独方法中,也不能在没有ClassA实例的情况下调用它。是否可以在Mockito(或任何其他模拟库)中执行此操作而无需重写大量代码?我愿意进行小的代码更改,以使其更易于测试。
最佳答案
为了模拟ExternalObject
,您必须能够提供在测试流程中使用的ExternalObject
实例。
只要在ExternalObject
中创建public ClassA(String string)
,这将很困难。
为了使您的ClassA
更具可测试性,您需要在构造ExternalObject
时提供ClassA
的实例。
例如:
class ClassA{
private ExternalObject externalObject;
public ClassA() {
super();
}
public ClassA(ExternalObject externalObject, String string) {
super();
this.externalObject = externalObject.parseString(string);
}
}
然后可以如下进行测试:
public class ClasssATest {
@Test
public void someTest() {
String input = "a string";
ExternalObject externalObject = Mockito.mock(ExternalObject.class);
Mockito.when(externalObject.parseString(eq(input))).thenReturn(externalObject);
ClassA sut = new ClassA(externalObject, input);
...
}
}
这里的关键点是:将外部依赖项注入您的类中。进行更改后,测试将变得更加容易,并且更广泛地讲,通过交换该外部依赖项的实现,此方法可以更轻松地更改系统行为。