@InjectMocks is the Mockito Annotation. It allows you to mark a field on which an injection is to be performed. Injection allows you to, Enable shorthand mock and spy injections.
@InjectMocks is a Mockito mechanism for injecting declared fields in the test class into matching fields in the class under test. It doesn't require the class under test to be a Spring component. @Autowired is Spring's annotation for autowiring a bean into a production, non-test class.
React + Spring Boot Microservices and Spring The @Autowired annotation can be used to autowire bean on the setter method just like @Required annotation, constructor, a property or methods with arbitrary names and/or multiple arguments.
You have three choices here: Do actual Spring autowiring in your tests. Use injection methods that can legitimately be performed by your tests (constructor parameters, public setters, public fields - in order of preference) Use reflection to inject your mocks.
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)
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);
}
}
In addition to accepted answer, if you are using spring-boot, it's easier to use @MockBean annotation (that creates a mock and add it as a bean to the context, replacing it if it exists):
@RunWith(SpringRunner.class)
public class aTest () {
@MockBean
private B b;
@MockBean
private C c;
@Autowired
private A a;
}
In case you are not using spring-boot, the problem with @Autowired + @InjectMocks is that Spring will load unneeded instances for beans B and C first, and then they are replaced by the mocks. This is a waste and could have transitive dependencies that you don't want/can't load. It's always recommended to load the minimum Spring context for your testing. I would recommend this:
@RunWith(SpringRunner.class)
@Import({A.class, D.class})
@ContextConfiguration(classes = aTest.class)
public class aTest () {
@Bean
private B b() {
return Mockito.mock(B.class);
}
@Bean
private C c() {
return Mockito.mock(C.class);
}
@Autowired
private A a;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With