测试非存储库方法时如何做等同于 "when, thenReturn" 的事情
How to do something equivalent to "when, thenReturn" when you are testing a non-repository method
我正在 Spring Boot JUnit 中编写一些测试代码,并且在使用存储库方法的测试用例中取得了成功,使用 "when, thenReturn"
如下所示。
@ExtendWith(SpringExtension.class)
@WebMvcTest
public class PictionarizerapiUserControllerTests {
@MockBean
private UserRepository userRepository;
@MockBean
private UserController userController;
@Autowired
private MockMvc mockMvc;
@Test
@DisplayName("When an update request is sent, the User data gets updated properly, and the updated User data gets returned in a form of JSON")
public void testUpdateUser() throws Exception {
// User before update
User existingUser = new User();
existingUser.setId(28);
existingUser.setName("Alex");
......
......
// return the User (before update) that is fetched by UserRepository#findById() with ID=28
when(userRepository.findById(28)).thenReturn(Optional.of(existingUser));
// UserRepository#save() returns the fetched entity as it is
when(userRepository.save(any())).thenAnswer((invocation) -> invocation.getArguments()[0]);
......
......
我想我也可以为我自己写的控制器方法写一个测试用例,我试着做如下“when, thenReturn”。
@Test
@DisplayName("When correct login information is given and the matched user is fetched")
public void testCheckIfValidUserFound() throws Exception {
Integer userIdObj = Integer.valueOf(28);
String requestEmail = "alex.armstrong@example.com";
String requestPassword = "MajorStateAlchemist";
when(userController.checkIfValidUser(requestEmail, requestPassword)).thenReturn(Optional.of(userIdObj));
......
......
}
但是,我收到一条错误消息 The method thenReturn(ResponseEntity<capture#1-of ?>) in the type OngoingStubbing<ResponseEntity<capture#1-of ?>> is not applicable for the arguments (Optional<Integer>)
。我做了一些研究,了解到只有在测试存储库方法时才能使用 "when, thenReturn"
语法,这些方法是 JPA 中内置的方法,例如 findById()
等(除非我弄错了),在我的例子中它不起作用,因为我要测试的是我自己创建的方法,而不是 JPA 的内置存储库方法。
我的问题来了。
当我测试存储库方法以外的东西时,如何编写等同于 "when, thenReturn"
的东西?
更新
我自己的方法是这样定义的
@RequestMapping(value = "/login", method = RequestMethod.GET)
public ResponseEntity<?> checkIfValidUser(
@RequestParam("email") String email,
@RequestParam("password") String password) {
int userId = 0;
List<User> userList = repository.findAll();
for(User user: userList) {
String userEmail = user.getEmail();
String userPassword = user.getPassword();
String inputEmail = email;
String inputPassword = password;
if(userEmail.equals(inputEmail) && userPassword.equals(inputPassword)) {
userId = user.getId();
}
}
if(userId > 0) {
Integer userIdObj = Integer.valueOf(userId);
return new ResponseEntity<>(userIdObj, HttpStatus.OK);
} else {
return new ResponseEntity<>(
new Error("The email address and the password don't match"),
HttpStatus.NOT_FOUND
);
}
}
您要测试的方法似乎是 testCheckIfValidUserFound()
,您不应该像这样模拟方法本身。
when(userController.checkIfValidUser(requestEmail, requestPassword)).thenReturn(Optional.of(userIdObj));
相反,您应该模拟的方法是 userRepository.findAll()
,因为这是您在控制器的 checkIfValidUser
方法中调用的存储库方法。
所以你的“when, thenReturn”部分应该是这样的。
when(userRepository.findAll()).thenReturn(Collections.singletonList(esixtingUser));
当你想检查returns是否是正确的值时,通常你需要指定你想检查哪个键的值,但在这种情况下,根据你的checkIfValidUser
方法如果搜索成功,它只是 returns 一个整数,因此在使用 jsonPath
.
断言时不应该有任何规范和美元符号
因此,在模拟存储库后,您可以像这样执行获取请求。
mockMvc.perform(MockMvcRequestBuilders.get("/login")
.param("email", requestEmail)
.param("password", requestPassword)
.with(request -> {
request.setMethod("GET")<
return request;
}))
.andExpect(MockMvcResultMatchers.status().is(HttpStatus.OK.value()))
.andExpect(jsonPath("$").value(28));
我正在 Spring Boot JUnit 中编写一些测试代码,并且在使用存储库方法的测试用例中取得了成功,使用 "when, thenReturn"
如下所示。
@ExtendWith(SpringExtension.class)
@WebMvcTest
public class PictionarizerapiUserControllerTests {
@MockBean
private UserRepository userRepository;
@MockBean
private UserController userController;
@Autowired
private MockMvc mockMvc;
@Test
@DisplayName("When an update request is sent, the User data gets updated properly, and the updated User data gets returned in a form of JSON")
public void testUpdateUser() throws Exception {
// User before update
User existingUser = new User();
existingUser.setId(28);
existingUser.setName("Alex");
......
......
// return the User (before update) that is fetched by UserRepository#findById() with ID=28
when(userRepository.findById(28)).thenReturn(Optional.of(existingUser));
// UserRepository#save() returns the fetched entity as it is
when(userRepository.save(any())).thenAnswer((invocation) -> invocation.getArguments()[0]);
......
......
我想我也可以为我自己写的控制器方法写一个测试用例,我试着做如下“when, thenReturn”。
@Test
@DisplayName("When correct login information is given and the matched user is fetched")
public void testCheckIfValidUserFound() throws Exception {
Integer userIdObj = Integer.valueOf(28);
String requestEmail = "alex.armstrong@example.com";
String requestPassword = "MajorStateAlchemist";
when(userController.checkIfValidUser(requestEmail, requestPassword)).thenReturn(Optional.of(userIdObj));
......
......
}
但是,我收到一条错误消息 The method thenReturn(ResponseEntity<capture#1-of ?>) in the type OngoingStubbing<ResponseEntity<capture#1-of ?>> is not applicable for the arguments (Optional<Integer>)
。我做了一些研究,了解到只有在测试存储库方法时才能使用 "when, thenReturn"
语法,这些方法是 JPA 中内置的方法,例如 findById()
等(除非我弄错了),在我的例子中它不起作用,因为我要测试的是我自己创建的方法,而不是 JPA 的内置存储库方法。
我的问题来了。
当我测试存储库方法以外的东西时,如何编写等同于 "when, thenReturn"
的东西?
更新
我自己的方法是这样定义的
@RequestMapping(value = "/login", method = RequestMethod.GET)
public ResponseEntity<?> checkIfValidUser(
@RequestParam("email") String email,
@RequestParam("password") String password) {
int userId = 0;
List<User> userList = repository.findAll();
for(User user: userList) {
String userEmail = user.getEmail();
String userPassword = user.getPassword();
String inputEmail = email;
String inputPassword = password;
if(userEmail.equals(inputEmail) && userPassword.equals(inputPassword)) {
userId = user.getId();
}
}
if(userId > 0) {
Integer userIdObj = Integer.valueOf(userId);
return new ResponseEntity<>(userIdObj, HttpStatus.OK);
} else {
return new ResponseEntity<>(
new Error("The email address and the password don't match"),
HttpStatus.NOT_FOUND
);
}
}
您要测试的方法似乎是 testCheckIfValidUserFound()
,您不应该像这样模拟方法本身。
when(userController.checkIfValidUser(requestEmail, requestPassword)).thenReturn(Optional.of(userIdObj));
相反,您应该模拟的方法是 userRepository.findAll()
,因为这是您在控制器的 checkIfValidUser
方法中调用的存储库方法。
所以你的“when, thenReturn”部分应该是这样的。
when(userRepository.findAll()).thenReturn(Collections.singletonList(esixtingUser));
当你想检查returns是否是正确的值时,通常你需要指定你想检查哪个键的值,但在这种情况下,根据你的checkIfValidUser
方法如果搜索成功,它只是 returns 一个整数,因此在使用 jsonPath
.
因此,在模拟存储库后,您可以像这样执行获取请求。
mockMvc.perform(MockMvcRequestBuilders.get("/login")
.param("email", requestEmail)
.param("password", requestPassword)
.with(request -> {
request.setMethod("GET")<
return request;
}))
.andExpect(MockMvcResultMatchers.status().is(HttpStatus.OK.value()))
.andExpect(jsonPath("$").value(28));