Spring Boot 在执行MockMvc的单元测试中获取NullPointerException

hmmo2u0o  于 2022-11-05  发布在  Spring
关注(0)|答案(2)|浏览(193)

我在我的应用程序的控制器中运行一个单元测试,我得到了一个NullPointerException。
控制器:

@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);
}
}

UserData只是一个简单的

public record UserData(String id, String name) {
}

这是我的测试类:

@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());
}

正如我所看到的,所有的注解都在正确的位置。但是当我运行一个测试时,我得到了如下的NullPointerException:

Cannot invoke "com.package.usersapi.service.UserService.getUsersForList()" because "this.userService" is null
zpgglvta

zpgglvta1#

我会作出以下修订:
1.在产品代码中:将UserService注入到控制器中,而不是在构造函数中创建一个:

@Autowired
public UserMigrationController(UserService userService) {
    this.userService = userService;
}

当前您没有与您在测试中创建的mock进行交互。UserService必须是一个springbean-用@Service注解它应该可以完成这项工作。
1.您在测试中使用了错误的注解。对于此类测试,@WebMvcTest是理想的选择:

@WebMvcTest(UserMigrationController.class)
class UserMigrationControllerTest {

@Autowired
private MockMvc mockMvc;

@MockBean
private UserService userService;

@Test
void should_get_users_for_list() throws Exception {
}

请参阅:使用@WebMvcTest进行单元测试
注意:您不再需要调用MockitoAnnotations.openMocks

ghg1uchk

ghg1uchk2#

事实上,我需要从Controller类的构造函数模拟存储库。测试类应该如下所示:

@AutoConfigureMockMvc
class UserMigrationControllerTest {

@Autowired
private MockMvc mockMvc;

@MockBean
private UserService userService;

@MockBean
private UserRepository userRepository;

@MockBean
private DocumentRepository documentRepository;

// the rest of the code

谢谢您的建议!

相关问题