'Setting up data for Mockito
I am unit testing my spring Rest API and I have had joy mocking my create and retrieve methods using the following structure.
@Test
public void getAllUsersReturnsAListOfAllTheUsersInJSONFormat() throws Exception {
List<User> users = new ArrayList<>();
users.add(new User("DelBoy"));
users.add(new User("Rodney_Trotter"));
users.add(new User("Uncle.Albert"));
Mockito.when(service.getAllUsers()).thenReturn(users);
mvc.perform(get("/api/users"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.hasSize(3)))
.andExpect(jsonPath("$[0].username", Matchers.equalTo("DelBoy")))
.andExpect(jsonPath("$[1].username", Matchers.equalTo("Rodney_Trotter")))
.andExpect(jsonPath("$[2].username", Matchers.equalTo("Uncle.Albert")));
}
However, I am trying to create a test for my Update and Delete methods. When I mock the methods they never behave as expected because there is no data to update or delete. After extensive research online I cannot find any information pointing to resolving this issue. My current attempt is the following code.
@Test
public void updateUserUpdatesAUserUponSuccess() throws Exception {
User updatedUser = new User(UUID.fromString("da3f6cae-9126-407b-a1ea-093bdac72434"), "Trigger");
Mockito.when(service.updateUser(updatedUser)).thenReturn(true);
Mockito.when(validator.validateUsername(updatedUser.getUsername())).thenReturn(true);
Mockito.when(validator.validateUUID(updatedUser.getUserId().toString())).thenReturn(true);
String str = mvc.perform(put("/api/users/da3f6cae-9126-407b-a1ea-093bdac72434/TriggersBroom"))
.andExpect(status().isOk()).andReturn().getResponse().getContentAsString();
System.out.println(str);
}
I am not sure how to have user data mocked so that when I make a PUT request it can update the user at the hex Id specified to a different username ("trigger" being the username). How I would like this to work is to have a small set of user objects that I can update when I mock my updateUser function so I can test the update user route actually updates a record. Currently it returns false because nothing is being updated but it should return true as I have tested manually in my development environment outside of unit testing and it works.
Note: The println was my was of checking what was actually returned and it was false.
Solution 1:[1]
How I would like this to work is to have a small set of user objects that I can update when I mock my updateUser function so I can test the update user route actually updates a record
This is because you write:
User updatedUser = new User(UUID.fromString("da3f6cae-9126-407b-a1ea-093bdac72434"), "Trigger");
Mockito.when(service.updateUser(updatedUser)).thenReturn(true);
Then you can see the updatedUser is not the same instance as the one you gonna call in the real service, it's just a instance you created above.
To mock this, you have 2 ways:
- If you can get the exactly same instance as the one you gonna call in real service, it will return
truefor you. - You can use
Mockito.eq(updatedUser)to mock. E.g.Mockito.when(service.updateUser(Mockito.eq(updatedUser))).thenReturn(true);But then you need to remember to override theequals()method for classUser. Then if you modify the methodequals(), you need to updatehashCode()as well
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | nnhthuan |
