我想测试一个用作包装器的类,它为下面的类提供抽象。
这意味着我需要在该类中创建一些对象,也就是说,我不通过构造函数或某种方法传递协作者。
例如,这是一个包装类:
public class Abstraction {
private ComplexClass complex;
public class Abstraction(some parameters) {
complex = new Complex(parameters);
}
}
为了能够测试这个类,我有一个想法,就是创建一个返回Complex类对象的方法,如下所示:
public class Abstraction {
private ComplexClass complex;
public class Abstraction(parameters) {
complex = createComplex(parameters);
}
protected createComplex ComplexClass(parameters) {
return new ComplexClass(parameters);
}
}
问题是,我不能使用Mockito来模拟我正在测试的类构造函数中创建的协作者。如何克服这个?
我的想法是窥探SUT以便createComplex返回模拟对象,但我不能这样做,因为需要先创建SUT。这是一种死锁。
我的最终目标是测试是否调用了一些协作者类的方法。
答案 0 :(得分:2)
测试此课程的业务优势是什么?它没有实现算法,也没有做出决定。如你所说,它只是一个包装。
你说你想测试某些方法是否被调用但这对任何人有何帮助?当然,测试确认在某些情况下调用这些方法而不是其他情况,换句话说是对业务逻辑的测试,将会更加有用。这里存在的风险是,您将最终进行难以维护的复杂测试,并引入惯性,这将使未来的重新分解变得更加困难和昂贵。你希望有什么奖励能让这种风险变得有价值?
答案 1 :(得分:1)
你可以在测试用例
中使用一个相当简单的匿名内部类来完成它ComplexClass mock = Mockito.mock(ComplexClass.class);
Abstraction abstraction = new Abstraction("foo") {
@Override
protected ComplexClass createComplex(parameters) {
return mock;
}
};
assertTrue("bar", abstraction.doStuff());
答案 2 :(得分:1)
您可以为ComplexClass
上设置的Abstraction
实施factory:
public class ComplexClassFactory {
public ComplexClass create(parameters) {
return new ComplexClass(parameters);
}
}
public class Abstraction {
private ComplexClassFactory complexClassFactory;
public void setComplexClassFactory(ComplexClassFactory complexClassFactory) {
this.complexClassFactory = complexClassFactory;
}
private ComplexClass complex;
public class Abstraction(parameters) {
complex = complexClassFactory.create(parameters);
}
}
答案 3 :(得分:1)
一种可能性是为ComplexClass
类(我命名为Complex
)提取一个接口,并提供一个替代构造函数,仅用于测试目的注入一个实例新创建的Complex
接口:
public class Abstraction {
private Complex complex;
public Abstraction(String parameters) {
this.complex = new ComplexClass(parameters);
}
Abstraction(Complex complex) {
this.complex = complex;
}
public class ComplexClass implements Complex {
private final String parameters;
public ComplexClass(String parameters) {
this.parameters = parameters;
}
}
interface Complex {
}
}
这样你可以为Complex
接口创建一个模拟器,使用接收Complex
实例的构造函数并独立测试 Abstraction 类:
@Test
public void testAbstraction() {
Complex mock = Mockito.mock(Complex.class);
Abstraction abstraction = new Abstraction(mock);
}