Reputation: 907
I have something like
private static final CustomObject ObjectA = new CustomObject();
@Mock
Foo1 foo1;
@Mock
Foo2 Foo2 = new Foo2(ObjectA);
@Mock
Foo3 foo3;
@InjectMocks
ContainerClass container;
I want to initialize Foo2 with ObjectA before it gets injected in container. The above code is not working.
EDIT: I am trying to mock Foo2 but there is an internal object of Foo2 which i want to initialize with a real object, so when i call methods of Foo2, this internal object is utilized to give me results i need based on the values i provided during its construction.
Upvotes: 6
Views: 8446
Reputation: 10777
Code style notwithstanding, the problem you have is that Foo2
isn't really a mock, because you're explicitly instantiating it. If you really want to use a "real" Foo2
instance that is instantiated with the Object2
instance, then consider using a @Spy
annotation on Foo2
. Then, the @InjectMocks
annotation should do what you are expecting.
Upvotes: 0
Reputation: 131486
The above code is not working.
1) @InjectMocks
uses much "magic" and is not necessary the clearest and debugable way to setup the mocks of the object under test.
Under the hoods, it tries multiple things : constructor injection, property setter injection, field injection.
But if it fails to inject, that will not report failure :
If any of the following strategy fail, then Mockito won't report failure; i.e. you will have to provide dependencies yourself.
As alternative you could so explicitly set the dependencies of the object under test.
2) Side but important note : name your variables with a lowercase as first letter. Naming them with the class name is not readable and conventional.
3) This doesn't make sense :
@Mock
Foo2 Foo2 = new Foo2(ObjectA);
You instantiate Foo2
that is then replaced by a Mockito mock.
Mocking Foo2
behavior but letting its ObjectA
dependency be a no mock object is not really logic.
By doing that, you don't mock really the dependencies of the object under test as your calling pattern is :
object under test -> mock dep1 -> real object dep2
In this case, writing an integration test (without mocks) makes more sense.
As you unit test ContainerClass
, you will test only the ContainerClass
behavior.
The ObjectA
method which you would like to get the result should be a call of Foo2
to ObjectA
which you mock the call to Foo2
in your test.
Note that you don't need to mock ObjectA
if you mock the method of its caller.
Here is a example :
public class Foo2{
private ObjectA objectA;
public Foo2(ObjectA objectA){
this.objectA = objectA;
}
public Bar callObjectA(){
return objectA.foo();
}
}
What you need to mock here is callToObjectA()
.
@Mock
Foo1 foo1;
@Mock
Foo2 foo2;
@Test
public void myMethod(){
ContainerClass container = new ContainerClass(foo1, foo2);
Bar mockedBar = new Bar(....);
Mockito.when(foo2.callObjectA()).thenReturn(mockedBar);
// invoke the method under test
container.myMethod();
// assertions ...
}
Upvotes: 2