Search code examples
javajunitmockingmockitoconstructor-injection

Mocking an attribute of a class regardless of constructor signature


Class

public class Foo {
  private MyClass obj;

  public Foo(String s, int i, boolean b) {
    MyOtherClass otherObj = OtherClassFactory.getInstance();
    this.obj = new MyClass(s, i, b, otherObj);
  }

  //More Code
}

Constructor takes some arguments, retrieves an instance from a factory, and uses all these local variables to instantiate the one attribute it has (obj).

However, all I care about is mocking obj itself. I don't care about any of the arguments to the constructor, nor otherObj.

I've tried injecting just the attribute:

public class FooTest {
  @Mock
  private MyClass fakeObj;
  @InjectMocks
  private Foo foo;

  //More Code
}

But this doesn't work, complaining:

Cannot instantiate @InjectMocks field named 'foo' of type 'class Foo'. You haven't provided the instance at field declaration so I tried to construct the instance. However the constructor or the initialization block threw an exception : OtherClassFactory has not been initialized.

Is what I'm trying to do possible, and if so how? If not, and I need to mock OtherClassFactory, how would I do that?


Solution

  • I would provide a second constructor, package-private, like this.

    public Foo(String s, int i, boolean b) {
        this(new MyClass(s, i, b, OtherClassFactory.getInstance());
    }
    
    Foo(MyClass obj) {
       this.obj = obj;
    }
    

    Then in your test, you can just write

    Foo toTest = new Foo(mockMyClass);
    

    where mockMyClass is your Mockito mock.