使用EasyMock测试构造另一个对象的方法

时间:2012-08-30 19:48:20

标签: java unit-testing easymock

我有这样的方法:

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通常如何做到这一点?

2 个答案:

答案 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所指出的那样。两种解决方案通常比将对象实例化与应用程序逻辑混合更好。