Mockito when()。thenReturn()在系统测试中不起作用

时间:2017-09-14 14:51:41

标签: java spring unit-testing junit mockito

我已经在这里阅读了所有其他主题,但找不到合适的解决方案。

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

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

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

@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,而不是尊重我从我给出的规则中预期的值。 这是一种非常奇怪的行为。为什么会这样?谢谢!

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

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

您应该使用匹配器:

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