Null pointer on an autowired bean which is not mocked by mockito
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.
Autowired fields of mocked object returns null in Mockito
You need to use the @InjectMocks annotation in your unit test :
@ExtendWith(MockitoExtension.class)
class StudentServiceTest {
@Mock
private StudentInstitutionMapper studentInstitutionMapper;
@InjectMocks
private StudentService studentService;
@Test
public void testStudentService_getPresentStudentCount1() {
StudentParams studentParam = mock(StudentParams.class);
Integer institutionTestId = 3539;
when(studentParam.getInstitutionTestId()).thenReturn(institutionTestId);
int i = studentService.getPresentStudentCount(studentParam);
assertEquals(0, i);
}
}
You should also configure the behavior of the studentInstitutionMapper in the unit test to make it return the expected result.
Mocking a autowired bean throws a NullPointerException
Because you are using Spring controller, you need to import your controller from SpringContext, by @Autowired annotation:
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest
public class MyControllerTest {
@MockBean
private ServiceA serviceA;
@Autowired // import through Spring
private MyController myController;
@Before
public void init() {
when(serviceA.getCurrentUser()).thenReturn(some object);
}
@Test
public void firstTest() {
myController.handleMessage(); // ---> Throws NPE stating that serviceA is null
}
}
@MockBean are added to SpringContext, so they will be injecte as a dependency to your controller.
Mockito Injecting Null values into a Spring bean when using @Mock?
For me it's unclear how the combination of Spring and Mockito as you took it from the referenced blog source should work at all as expected. At least I may explain your observation:
- Your test (
this.mockMvc.perform()
) is working on the web application context created by Spring. In that contextProductController
was instantiated by Spring (context:component-scan
). TheproductService
was then autowired with the Mockito mock you created inmvc-dispatcher-servlet.xml
assomeDependencyMock
. - If you inject the
mockproductService
via@Autowired
, Spring injects thesomeDependencyMock
instance from its context. So yourMockito.when()
call works correctly on this instance, which was already correctly wired to theProductController
as mentioned before. - But if you inject the
mockproductService
via@Mock
, Mockito injects a new instance ofProductService
, not the one of the Spring context, since it knows nothing about Spring at all. So yourMockito.when()
call does not operate on the mock which was autowired by Spring and thussomeDependencyMock
stays uninitialized.
So what's left unclear for me about how the original code from the blog worked at all is:
- The
productController
property annotated with@InjectMocks
will be initialized by Mockito and even correctly wired to themockproductService
in the test class. But Spring does not know anything about that object and won't use it inthis.mockMvc.perform()
calls. So I assume if you injectmockproductService
only with@Autowired
your test works as intended even if you delete both theproductController
property and theMockitoAnnotations.initMocks()
call in your test class.
Related Topics
How to Use Variables in One Method into Another Method
How to Check If a Record Exists Using Jpa
How to Click an Li Inside a Ul Using Selenium Webdriver
How to Get the Average of a 2D Array
Eclipse Console Not Showing Output
Remove Duplicate Values from Hashmap in Java
How to Change Read-Only Status of Files in Intellij
Check Date Between Two Other Dates Spring Data Jpa
Counting Unique Characters in a String
How to Replace Non-Printable Unicode Characters in Java
Jparepository Findall() Returns Empty Result
How to Split a String Between Letters and Digits (Or Between Digits and Letters)
How to Check Whether Kafka Server Is Running
How to Update Only the Incoming Fields in a Model Using Spring Data Jpa
How to Force a Method to Throw an Exception in Junit Testing
Convert String With Dot or Comma to Float Number
Spring Boot: Cannot Access Rest Controller on Localhost (404)