我有这样的方法:
public void MyMethod(int p1, int p2) {
//some logic here
MyObject mo = new MyObject(var1,var2);
int returnedId = mo.doOperation(something);
//Do something with the returnedId;
}
我想测试这个方法但是我不能模拟构造函数调用,因此围绕它的测试会破坏模块性。我可以使用工厂方法或其他东西,但因为我只有一个构造函数,所以没有意义。
使用EasyMock通常如何做到这一点?
答案 0 :(得分:1)
我不确定你是否可以逃离这里的工厂或将对象作为参数传递。它可能感觉像是一个额外痛苦的世界,但如果你期望模拟对象,你经常需要以特定的样式编码。
我会倾向于工厂方向(当然定义为界面)。
在调用getMyObject()
:
public void myMethod(int p1, int p2, MyObject mo) {
MyObject mo = factory.getMyObject(...args...);
int returnedId = mo.doOperation(something);
}
public interface SomeFactory {
MyObject getMyObject(...args...);
}
或者您可以创建一个接受MyObject
作为参数的方法的重载版本,但它有点难看:
// Test this one, mocking 'mo'
public void myMethod(int p1, int p2, MyObject mo) {
MyObject mo = new MyObject(var1,var2);
int returnedId = mo.doOperation(something);
}
public void myMethod(int p1, int p2) {
myMethod(p1, p2, new MyObject(...));
}
答案 1 :(得分:1)
仅限EasyMock不能这样做。但是有一些解决方法,比如使用PowerMock作为EasyMock的扩展,这样你就可以模拟静态方法,构造函数调用,最终方法等。
但在此之前,请仔细分析您的问题。您真的需要在MyObject
内创建MyMethod
吗?通常,以一种所有依赖关系作为构造函数参数或通过setter传递的方式来设计类要好得多。这种模式通常称为“依赖注入”。通过执行依赖注入,可以避免像您提到的那样的可测试性问题。
另外,MyMethod
可以将MyObject
作为参数,也可以由工厂获得,正如Duncan Jones所指出的那样。两种解决方案通常比将对象实例化与应用程序逻辑混合更好。