简体   繁体   English

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

[英]Using EasyMock to test a method that constructs another object

I have a method like this: 我有这样的方法:

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

I want to test this method but I can't mock the constructor call, so a test around this would break modularity. 我想测试这个方法,但我不能模拟构造函数调用,所以围绕它的测试会打破模块化。 I could do it with a factory method or something but since I only have one constructor there is no point. 我可以使用工厂方法或其他东西,但因为我只有一个构造函数没有意义。

How is this generally done using EasyMock? 这通常是如何使用EasyMock完成的?

I'm not sure you can escape a factory here or passing the object as an argument. 我不确定你是否可以逃离这里的工厂或将对象作为参数传递。 It may feel like a world of extra pain, but you often have to code in a particular style if you expect to mock objects. 它可能感觉像是一个额外的痛苦世界,但如果你期望模拟对象,你经常需要以特定的样式编码。

I would lean in the factory direction (defined as an interface, of course). 我会倾向于工厂方向(当然,定义为界面)。 Mock the factory and get it to return your mocked object when calling getMyObject() : 模拟工厂并在调用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...);    
}

Or you could create an overloaded version of the method that accepts a MyObject as an argument, but it's a bit ugly: 或者你可以创建一个接受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(...));
}

You can't do that with EasyMock only. 你不能只使用EasyMock。 But there are workaround solutions, like using PowerMock as an extension to EasyMock, so that you can mock static methods, constructor calls, final methods etc. 但是有一些解决方法,比如使用PowerMock作为EasyMock的扩展,这样你就可以模拟静态方法,构造函数调用,最终方法等。

But before doing that, analyze your problem carefully. 但在此之前,请仔细分析您的问题。 Do you really need to create MyObject inside MyMethod ? 你真的需要在MyMethod创建MyObject吗? In general, it is far better to design classes in a way that all its dependencies are passed in as constructor arguments or via setters. 通常,以一种所有依赖关系作为构造函数参数或通过setter传递的方式来设计类要好得多。 This is the pattern commonly called "dependency injection". 这种模式通常称为“依赖注入”。 By doing dependency injection, you avoid testability problems like the one you mentioned. 通过执行依赖注入,可以避免像您提到的那样的可测试性问题。

Also, MyMethod could take MyObject as a parameter or it could be obtained by a factory, as Duncan Jones points out. 另外,正如Duncan Jones指出的那样, MyMethod可以将MyObject作为参数,也可以由工厂获得。 Both solutions are usually better than mixing object instantiation with the application logic. 两种解决方案通常比将对象实例化与应用程序逻辑混合更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM