9

I have a looked at similar questions on this board, but none of them answer my question. This sound strange, but is it possible to mock out a constructor call on the object you're mocking.

Example:

class RealGuy {

   ....
   public void someMethod(Customer customer) {
     Customer customer = new Customer(145);
   }
}
class MyUnitTest() {
  public Customer customerMock = createMock(Customer.class)
  public void test1() {
    //i can inject the mock object, but it's still calling the constuctor
    realGuyobj.someMethod(customerMock);
    //the constructor call for constructor makes database connections, and such.
  }
}

How can I expect a constructor call? I can change the Customer constructor call to use newInstance, but im not sure if that will help. I have no control over what the body of the new Customer(145) constructor does.

Is this possible?

George Kagan
  • 5,913
  • 8
  • 46
  • 50
Setzer
  • 739
  • 4
  • 10
  • 18
  • It would be a good idea to not make database connections in a constructor. Inject the connections into the class using them. – matt b Oct 04 '11 at 20:31
  • Agreed. But I dont' have control over that Customer constructor logic. – Setzer Oct 05 '11 at 01:45

4 Answers4

19

you can do so with EasyMock 3.0 and above.

Customer cust = createMockBuilder(Customer.class)
     .withConstructor(int.class)
     .withArgs(145)
     .addMockedMethod("someMethod")
     .createMock();
betaboy00
  • 651
  • 6
  • 5
  • 1
    `createMockBuilder` will help you to create a partial mock of a class in the test code. This won't mock a constructor called in `someMethod`. – default locale Aug 08 '18 at 12:17
  • True. This will just create a mock object and not mock the constructor call. – rj4u Jun 15 '19 at 10:43
12

You can't do this with easymock, as it doesn't support mocking constructors. There's a library called powermock which can do that and is the only mocking library, as far as I know, that can stub constructors and static methods in Java.

Augusto
  • 28,839
  • 5
  • 58
  • 88
1
import static org.powermock.api.easymock.PowerMock.expectNew;

instance = new UsesNewToInstantiateClass();
expectNew(AnyOldClass.class).andReturn(anyClass);
Truong Ha
  • 10,468
  • 11
  • 40
  • 45
0

And this is why you want to inject your dependencies (via Guice or similar package) instead of creating them inside your class.

Then you don't HAVE TO mock their construction.

This assumes (a) that this is your code that you can change, and (b) that the objects in question are complex enough that you should inject them. Constructing simple objects inside your class are fine, but then you shouldn't need to mock them.

Charles Roth
  • 798
  • 5
  • 8