我正在测试一个Spring控制器,并且我已经模拟了我在其中调用的loginService。
我在单元测试中遇到了控制器响应的错误,但正如我在调试模式中看到的那样,两个元素的比较似乎完全相同。
下面你可以看到调试器的图像,它显示两个元素是等号。
现在让我们看看下面的代码。
受测系统(RestController.class)
@org.springframework.web.bind.annotation.RestController
public class RestController {
@Autowired
LoginService loginService;
...
//METHOD BEING TESTED
@RequestMapping(value = "/login", method = POST)
public ResponseEntity<JsonResponseBody> 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(); //get the User from the optional got from the DB
String jwt = loginService.createJwt(user.getId(), user.getUsername(), user.getPermission(), new Date());
//set the jwt token into the header of response
return ResponseEntity.status(HttpStatus.OK).header("jwt", jwt).body(new JsonResponseBody(HttpStatus.OK.value(),"Success! User logged in." + jwt));
}
}catch(UserNotLoggedException e1){ //thrown by loginService#getUserFromDbAndVerifyPassword
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new JsonResponseBody(HttpStatus.FORBIDDEN.value(),"Login failed! Wrong credentials. " + e1.toString()));
}catch(UnsupportedEncodingException e2){ //thrown by loginService#createJwt
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new JsonResponseBody(HttpStatus.FORBIDDEN.value(),"Login failed! Encoding permission token error. " + e2.toString()));
}
//send response to client
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new JsonResponseBody(HttpStatus.FORBIDDEN.value(),"Login failed! No corrispondence found into the database of users."));
}
...
//INNER CLASS USING LOMBOK
@AllArgsConstructor
public class JsonResponseBody{
@Getter @Setter
private int server;
@Getter @Setter
private Object response;
}
...
}
测试类:
@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(eq(user.getId()), eq(user.getUsername()), eq(user.getPermission()), any(Date.class))).thenReturn(jwt);
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
boolean areTheyEquals=false;
if((RestController.JsonResponseBody) serverResponse.getBody() == responseBody){
areTheyEquals = true;
}
assertEquals(areTheyEquals, true); //FALSE?!?!?!?!?
assertThat((RestController.JsonResponseBody) serverResponse.getBody(), is(responseBody)); //FALSE?!?!?!
}
}
最后两个断言结果为假。当我调试这个测试时,我发现模拟似乎是正确的,并且在断言之前,被比较的两个对象看起来绝对等于。 JUnit给出的错误是:
java.lang.AssertionError:期望:是 com.example.bytecode.SpringBootJWT.controllers.RestController$JsonResponseBody@587c290d
但是:是的 com.example.bytecode.SpringBootJWT.controllers.RestController$JsonResponseBody@4516af24
您可以在下面看到调试器的图像。
答案 0 :(得分:1)
此块中有两种不同类型的断言:
boolean areTheyEquals=false;
if((RestController.JsonResponseBody) serverResponse.getBody() == responseBody){
areTheyEquals = true;
}
assertEquals(areTheyEquals, true); //FALSE?!?!?!?!?
assertThat((RestController.JsonResponseBody) serverResponse.getBody(), is(responseBody)); //FALSE?!?!?!
目前还不清楚你的代码是否达到了第二个断言(assertThat(...)
),但有一些事情是明确的:
==
断言相等只有在比较相同实例assertThat((RestController.JsonResponseBody) serverResponse.getBody(), is(responseBody))
失败,则equals()
上的RestController.JsonResponseBody
方法认为这两个实例不同,所以:
equals()
上的RestController.JsonResponseBody
方法无法按预期执行RestController.JsonResponseBody
实例真的不同equals()
上没有RestController.JsonResponseBody
方法,所以它只是向父母调用super
来评估对象相等性我建议:
equals()
上添加RestController.JsonResponseBody
方法,或者只使用Mockito的refEq()
来应用简单的基于反思的相等检查assertEquals(areTheyEquals, true);