简体   繁体   中英

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?

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() :

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:

// 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. 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.

But before doing that, analyze your problem carefully. Do you really need to create MyObject inside MyMethod ? 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. 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. Both solutions are usually better than mixing object instantiation with the application logic.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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