java—在测试非存储库方法时,如何执行与“when,thenreturn”等效的操作

t0ybt7op  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(507)

我正在springbootjunit中编写一些测试代码,并在一个使用存储库方法的测试案例中获得了成功,使用 "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
            );
        }
    }
u3r8eeie

u3r8eeie1#

似乎你想测试的方法是 testCheckIfValidUserFound() ,您不应该这样嘲笑方法本身。

when(userController.checkIfValidUser(requestEmail, requestPassword)).thenReturn(Optional.of(userIdObj));

相反,你应该嘲笑的方法是 userRepository.findAll() 因为这是您在 checkIfValidUser 方法。
所以你的“何时返回”部分应该是这样的。

when(userRepository.findAll()).thenReturn(Collections.singletonList(esixtingUser));

当您想检查测试是否返回正确的值时,通常需要指定要检查的键的值,但在这种情况下,根据您的 checkIfValidUser 方法如果搜索成功,它只返回一个整数,因此在Assert时不应该有任何与美元符号一起的规范 jsonPath .
因此,在模拟存储库之后,可以像这样执行get请求。

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

相关问题