Reputation: 3215
I'm testing a Spring controller and I've mocked the loginService which I call in it.
I got errors in Unit Testing on the response of the controller but, as I can see in debug mode, the two elements compared seem exactly the same.
Below you can see the image of the debugger that shows that the two elements are equals.
Now let's see the code below.
System Under Test (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;
}
...
}
Test class:
@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?!?!?!
}
}
The last two asserts result false. When I debug this test I discover how the mock seems to be correct and also, before the asserts the two objects being compared seem absolutely equals. The error given by JUnit is this:
java.lang.AssertionError: Expected: is com.example.bytecode.SpringBootJWT.controllers.RestController$JsonResponseBody@587c290d
but: was com.example.bytecode.SpringBootJWT.controllers.RestController$JsonResponseBody@4516af24
Below you can see the image of the debugger.
Upvotes: 0
Views: 3606
Reputation: 47895
There are two different types of assertion in this block:
boolean areTheyEquals=false;
if((RestController.JsonResponseBody) serverResponse.getBody() == responseBody){
areTheyEquals = true;
}
assertEquals(areTheyEquals, true); //FALSE?!?!?!?!?
assertThat((RestController.JsonResponseBody) serverResponse.getBody(), is(responseBody)); //FALSE?!?!?!
It's unclear whether your code ever reaches the second assertion (assertThat(...)
) but a few things are clear:
==
will only work if you are comparing the same instanceassertThat((RestController.JsonResponseBody) serverResponse.getBody(), is(responseBody))
fails then the equals()
method on RestController.JsonResponseBody
has deemed these two instances to be different so either:
equals()
method on RestController.JsonResponseBody
does not do what you expect it to doRestController.JsonResponseBody
are genuinely differentequals()
method on RestController.JsonResponseBody
so it is just calling super
to a parent which just evaluates object equalityI would suggest:
equals()
method on RestController.JsonResponseBody
or just use Mockito's refEq()
to apply a simple, reflection based equality checkassertEquals(areTheyEquals, true);
Upvotes: 1