A @SpringBootTest is a test that actually starts up a Spring container along with the beans of the application.
@Autowired fields in tests behave like they do in normal Spring-Beans; they get injected with the actual beans configured in the application (xml, @Bean in a @Configuration, or @Component/@Service).
@MockBean creates a mock that they behave like normal mocks that you can control with when/then
etc and check with verify
and suchlike. The thing that is special about them is that they get injected into other beans in the context (for instance when you call Mockito.initAnnotations(this)
).
@InjectMocks
annotation tells to Mockito to inject all mocks (objects annotated by @Mock
annotation) into fields of testing object. Mockito uses Reflection for this.
@Autowired
annotation tells to Spring framework to inject bean from its IoC container. Spring also uses reflection for this when it is private field injection. You can even use even use @Inject
annotation (part of Java EE specification) with the same effect.
But I would suggest to look at benefits of Constructor injection over Field injection. In that case you don’t need to use @InjectMocks
at all, because you can pass mocks into testing object via constructor. There wouldn’t be Reflection needed under the hood in your test nor in production.
If you want to create integration test with subset of Spring beans I would suggest to take a look at @DirtiesContext
annotation. It is part of Spring framework module commonly called “Spring Test”.
https://lkrnac.net/blog/2014/02/promoting-constructor-field-injection/