How to use @InjectMocks along with @Autowired annotation in Junit

I have a class A which is using 3 differnt classes with autowiring

public class A () {

    @Autowired
    private B b;

    @Autowired
    private C c;

    @Autowired
    private D d;
}

While testing them, i would like to have only 2 of the classes (B & C) as mocks and have class D to be Autowired as normal running, this code is not working for me:

@RunWith(MockitoJUnitRunner.class)
public class aTest () {

    @InjectMocks
    private A a;

    @Mock
    private B b;

    @Mock
    private C c;

    @Autowired
    private D d;
}

Is it even possible to do so?


Solution 1:

It should be something like

@RunWith(SpringJUnit4ClassRunner.class)
public class aTest () {

    @Mock
    private B b;

    @Mock
    private C c;

    @Autowired
    @InjectMocks
    private A a;

}

If you want D to be Autowired dont need to do anything in your Test class. Your Autowired A should have correct instance of D. Also i think you need to use SpringJUnit4ClassRunner for Autowiring to work, with contextConfiguration set correctly. Because you are not using MockitoJunitRunner you need to initialize your mocks yourself using

MockitoAnnotations.initMocks(java.lang.Object testClass)

Solution 2:

I was facing same problem and tried the answer by Sajan Chandran. It didn't work in my case because I'm using @SpringBootTest annotation to load only a subset of all my beans. The goal is not to load the beans that I'm mocking since they have lot of other dependencies and configurations.

And I found the following variant of the solution to work for me, which is usable in normal case also.

@RunWith(SpringRunner.class)
@SpringBootTest(classes={...classesRequired...})
public class aTest () {

    @Mock
    private B b;

    @Mock
    private C c;

    @Autowired
    @Spy
    private D d;

    @InjectMocks
    private A a;

    @Before
    public void init(){
        MockitoAnnotations.initMocks(this);
    }

}