Issue
I'm running a Unit test In my application's Controller and I'm getting a NullPointerException. Here are the details.
The Controller:
@RestController
@CrossOrigin
@RequestMapping("/api/users")
public class UserMigrationController {
UserService userService;
@Value("${SOURCE_DNS}")
private String sourceDns;
@Autowired
public UserMigrationController(UserRepository userRepository, DocumentRepository documentRepository) {
userService = new UserService(userRepository, documentRepository);
}
@GetMapping(value = "/getUsers", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<UserData>> getUsersForList() throws Exception {
List<UsersData> usersDataList = UserService.getUsersForList();
return new ResponseEntity<>(usersDataList, HttpStatus.OK);
}
}
The UserData is just a simple
public record UserData(String id, String name) {
}
And here is my test class:
@AutoConfigureMockMvc
class UserMigrationControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@BeforeEach
void setup() {
MockitoAnnotations.openMocks(this);
}
@Test
void should_get_users_for_list() throws Exception {
String id = "id";
String name = "name";
UserData userData = new UserData(id, name);
List<UserData> response = new ArrayList<>();
response.add(userData);
when(userService.getUsersForList())
.thenReturn(response);
mockMvc.perform(
MockMvcRequestBuilders.get("/api/users/getUsers")
.contentType(MediaType.APPLICATION_JSON)
.accept("application/json"))
.andExpect(MockMvcResultMatchers.status().isOk());
}
As I can see, all annotations are in the right place. But when I run a test, I get NullPointerException like this:
Cannot invoke "com.package.usersapi.service.UserService.getUsersForList()" because "this.userService" is null
Solution
Turns out, I needed to mock repositories from the constructor in the Controller class. The test class should look like this:
@AutoConfigureMockMvc
class UserMigrationControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@MockBean
private UserRepository userRepository;
@MockBean
private DocumentRepository documentRepository;
// the rest of the code
Thank you for your suggestions!
Answered By - pussyCat
Answer Checked By - Mildred Charles (JavaFixing Admin)