【问题标题】:Mockito when().thenReturn() doesn't work in System Under TestMockito when().thenReturn() 在被测系统中不起作用
【发布时间】:2017-09-14 14:51:41
【问题描述】:

我已阅读此处的所有其他主题,但找不到正确的解决方案。

我正在测试一个控制器,它调用我想模拟的服务。 如果在测试中我控制了when().thenReturn() 规则的结果,那么它可以正常工作。

当我在被测系统(即我的控制器)中调试并检查定义的规则是否有效且已应用时,该规则根本没有应用,它返回一个空值,而不是我想要的那个。让我们深入了解我的代码!

这是我的控制器方法,即被测系统:

@RequestMapping(value = "/login", method = POST)
public ResponseEntity<Object> loginUser(@RequestParam(value ="id") String id, @RequestParam(value="password") String pwd){
   try {
      Optional<User> userr = loginService.getUserFromDbAndVerifyPassword(id, pwd);      //verify the presence into the database
      if (userr.isPresent()) {
         User user = userr.get();  
         String jwt = loginService.createJwt(user.getId(), user.getUsername(), user.getPermission(), new Date());
         return ResponseEntity.status(HttpStatus.OK).header("jwt", jwt).body(new JsonResponseBody(HttpStatus.OK.value(),"Success! User logged in." + jwt));
      }
   }catch(UserNotLoggedException e1){ 
      return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new JsonResponseBody(HttpStatus.FORBIDDEN.value(),"Login failed! Wrong credentials. " + e1.toString()));
   }catch(UnsupportedEncodingException e2){
      return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new JsonResponseBody(HttpStatus.FORBIDDEN.value(),"Login failed! Encoding permission token error. " + e2.toString()));
   }
   return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new JsonResponseBody(HttpStatus.FORBIDDEN.value(),"Login failed! No corrispondence found into the database of users."));
}

这是我的带有测试方法的测试类:

@RunWith(MockitoJUnitRunner.class)
public class RestControllerTest {

   @InjectMocks
   RestController restController;

   @Mock
   LoginService loginService;


   @Test
   public void loginUserWithSuccessTest() throws UserNotLoggedException, UnsupportedEncodingException{
       User user = new User("BDAGPP32E08F205K", "Pippo Baudo", "ILoveSanRemoEncrypted", "conduttore");
       Optional<User> fakeUserOptional = Optional.of(user);
       when(loginService.getUserFromDbAndVerifyPassword("BDAGPP32E08F205K","ILoveSanRemo")).thenReturn(fakeUserOptional);

       String jwt = "aaaa.bbbb.cccc";
       when(loginService.createJwt(user.getId(), user.getUsername(), user.getPermission(), new Date())).thenReturn(jwt);
       //I've tested also: when(loginService.createJwt(any(), any(), any(), any())).thenReturn(jwt);

       //This is TRUE: assertEquals(loginService.createJwt(user.getId(), user.getUsername(), user.getPermission(), new Date()), jwt); TRUE

       //THIS IS THE METHOD BEING TESTED
       ResponseEntity serverResponse = restController.loginUser("BDAGPP32E08F205K","ILoveSanRemo");
       RestController.JsonResponseBody responseBody = restController.new JsonResponseBody(HttpStatus.OK.value(), "Success! User logged in." + jwt);

       assertEquals(serverResponse.getStatusCode(), HttpStatus.OK); //TRUE
       assertThat(serverResponse.getBody(), is(responseBody)); //FALSE because jwt is NULL!!!!
   }
}

因此,Mockito 规则在被测试的方法之外起作用。 在其中,loginService.createJwt() 给了我一个 jwt null,而不是尊重我对我给出的规则所期望的值。 这是一个非常奇怪的行为。为什么呢?谢谢!

【问题讨论】:

    标签: java spring unit-testing junit mockito


    【解决方案1】:
    when(loginService.createJwt(user.getId(), user.getUsername(), user.getPermission(), new Date())).thenReturn(jwt);
    

    这几乎总是会失败,因为在模拟设置和实际调用时日期会有所不同。

    when(loginService.createJwt(any(), any(), any(), any()))
    

    这也是狡猾和模糊的。

    我会尝试:

    import static org.mockito.ArgumentMatchers.*;
    
    ...
    
    when(loginService.createJwt(eq(user.getId()), eq(user.getUsername()), eq(user.getPermission()), any(Date.class))).thenReturn(jwt);
    

    【讨论】:

      【解决方案2】:

      这是因为匹配 new Date() 不起作用,因为这是一个新对象,而不是实际传递给方法的对象。

      您应该改用匹配器:

      when(loginService.createJwt(user.getId(), user.getUsername(), user.getPermission(),
             Matchers.any(Date.class)).thenReturn(jwt);
      

      【讨论】:

      • 非常有用的答案。谢谢!唯一的问题是,我发现只有使用 Hamcrest 匹配器实现整行时才能使用 Hamcrest 匹配器。
      • 很高兴能帮上忙。你知道我认为我以前从未将匹配器与实际期望值混合在一起。我一直认为它会起作用!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-23
      • 2017-07-21
      • 2016-01-12
      • 1970-01-01
      相关资源
      最近更新 更多