0

我有这样的方法:

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 完成的?

4

2 回答 2

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...);    
}

或者您可以创建一个接受 aMyObject作为参数的方法的重载版本,但这有点难看:

// 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(...));
}
于 2012-08-30T20:09:43.560 回答
1

仅使用 EasyMock 无法做到这一点。但是有一些变通的解决方案,比如使用PowerMock作为 EasyMock 的扩展,这样您就可以模拟静态方法、构造函数调用、最终方法等。

但在此之前,请仔细分析您的问题。你真的需要在MyObject里面创建MyMethod吗?一般来说,设计类要好得多,其所有依赖项都作为构造函数参数或通过 setter 传入。这就是通常称为“依赖注入”的模式。通过进行依赖注入,您可以避免像您提到的那样的可测试性问题。

Also, MyMethod could take MyObject as a parameter or it could be obtained by a factory, as Duncan Jones points out. Both solutions are usually better than mixing object instantiation with the application logic.

于 2012-08-30T20:18:20.020 回答