Null pointer on an autowired bean which is not mocked by mockito
The issue you are facing is due to the use of @InjectMocks
annotation.@InjectMocks
marks a field on which injection should be performed. Mockito will try to inject mocks only either by constructor injection, setter injection, or property injection – in this order. If any of the given injection strategy fail, then Mockito won’t report failure.
So in your case when trying to inject mocks only one mock bean is present and the other bean ServiceA is not getting injected.To solve this issue :
You can try not using @InjectMocks
at all instead pass a mock object for the method that you want to mock while pass rest of the autowired objects into the constructor.Example :
Here to test i am passing one mock object and one autowired object.
@RunWith(MockitoJUnitRunner.class)
public class SampleTestServiceImplTest {
@Mock
private SampleClient sampleClient;
@Autowired
private BackendService backendService ;
private BackendServiceImpl backendServiceimpl;
@Before
void setUp() {
backendServiceimpl = new BackendServiceImpl(sampleClient, backendService);
}
Or another way you can make this work is by using @Autowired
annotation along with the @InjectMocks.@Autowired @InjectMocks
are used together and what it will do is inject the mocked class and Autowired annotation adds any other dependency which the class might have.
Answer referred from : https://medium.com/@vatsalsinghal/autowired-and-injectmocks-in-tandem-a424517fdd29
Usually when unit testing you want to mock all external dependencies of a class. That way the unit test can remain independent and focused on the class under test.
Nevertheless, if you want to mix Spring autowiring with Mockito mocks, an easy solution is to annotate with both @InjectMocks
and @Autowired
:
@InjectMocks
@Autowired
private UploadServiceImpl uploadService;
The net effect of this is that first Spring will autowire the bean, then Mockito will immediately overwrite the mocked dependencies with the available mocks.