The application runs in JEE environment. I wish inject a Spy into a bean under test. The Spy object has also some beans inside that should be injected. How can inject mocks of those beans into the Spy?
This is the usecase:
package testinject2;
import javax.inject.Inject;
public class ABean {
@Inject
BBean b;
public void print() {
System.out.println("Hi, I'm ABean");
b.print();
}
}
package testinject2;
import javax.inject.Inject;
public class BBean {
@Inject
CBean c;
public void print() {
System.out.println("Hi, I'm BBean");
c.print();
}
}
package testinject2;
public class CBean {
public void print() {
System.out.println("Hi, I'm CBean");
}
}
package testinject2;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class ABeanTest {
@Spy
CBean c = new CBean();
@Spy
BBean b = new BBean();
@InjectMocks
ABean beanUnderTest;
@Test
public void test() {
beanUnderTest.print();
}
}
I'm expect to obtain
Hi, I'm ABean
Hi, I'm BBean
Hi, I'm CBean
But instead I have a null ponter exception because CBean is not injected into BBean.
Which is the correct way to Inject a Spy object into another Spy ?
You need to define to which object mocks should be injected via @InjectMocks
annotation, but it does not work together with @Spy
annotation. See mockito issue.
There is the simplest solution to use Mockito.spy
instead of @Spy
together with @InjectMocks
:
@InjectMocks
BBean b = Mockito.spy(new BBean());
Full test code:
@RunWith(MockitoJUnitRunner.class)
public class ConfigTestObject {
@Spy
CBean c = new CBean();
@InjectMocks
BBean b = Mockito.spy(new BBean());
@InjectMocks
ABean beanUnderTest;
@Test
public void test() {
beanUnderTest.print();
//verify that mocks is working
verify(c, atLeast(1)).print();
verify(b, atLeast(1)).print();
}
}