I have a Controller Unit test using Mockito and MockMvc.
After a POST request, the POSTed object is resolved correctly, but my repository mock is not triggered.
Here is the mock code:
Date mydate = new Date();
Notification not = new Notification();
not.setId(-1L);
not.setUserid("BaBlubb");
not.setTimestamp(mydate);
not.setContent("MyContent");
Notification not2 = new Notification();
not2.setId(1L);
not2.setUserid("BaBlubb");
not2.setTimestamp(mydate);
not2.setContent("MyContent");
when(notificationRepository.save(not)).thenReturn(not2);
So this really just should simulate the saving of an object (ID is set and a route is generated out of it).
Unfortunately, the repository always returns null, so my code later fails when trying to return a new created Route out of null.
The mocks are correctly injected and do work for e.g. String comparison or if I only check for the function to have been called, I just can't get it to trigger on Objects.
The same issue occurs on
verify(notificationRepository, times(1)).save(not);
it does not trigger.
The questions would be: 1.) Why does the mock not trigger? I suppose it does not check for value equality in the object, but for object identifiers, which are not the same since the object is serialized and de-serialized in between.
2.) How can I get a generic mock? e.g. whenever repository.save() is called, no matter the parameter, it always should perform a specific way, e.g. instead of
when(notificationRepository.save(not)).thenReturn(not2);
I'd like to have
when(notificationRepository.save()).thenReturn(not2);
P.S. If for whatever reason you need the rest of the code, here is the submitted part, object is the json representation of the notification (with jackson)
mockMvc.perform(post("/api/notification").content(object)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON));
and here is the Controller header, the Object is de-serialized perfectly, the values are 1:1 the same
@RequestMapping(method=RequestMethod.POST)
public ResponseEntity<?> postNotification(@RequestBody Notification n) {
logger.debug("Saving userid "+n.getId());
Thanks for helping.
By default, Mockito delegates to your object's
equals
method. If you haven't overridden that, then it checks references by default. The following two lines are equivalent:If all Notification objects with the same fields are the same, then overriding
equals
andhashCode
will get you where you need to go. Beware, though, that this may have unintended side-effects with regard to Set and Map behavior, especially if your Notification objects don't have an ID until they are saved.With Matchers, this is very simple:
Though Matchers are very powerful, beware: they have some tricky rules associated with their use.