Reputation: 7104
How can I create a unit test for this service:
public class UserService {
private Map<String, User> userStorage = new HashMap<>();
public void saveOrUpdate(User user) {
User userFromStorage = userStorage.get(user.getId());
if (userFromStorage == null) {
userStorage.put(user.getId(), user);
} else {
userFromStorage.setName(user.getName());
userStorage.put(userFromStorage.getId(), userFromStorage);
}
}
}
How can I check that user creates or update successfully?
I can change void
to User
and return updated user and create this:
assertEquals(user.getName(), updatedUser.getName())
But what if I can't change method signature? How can I test it?
Upvotes: 0
Views: 873
Reputation: 6335
I would not mock anything here.
you have a HashMap and a User. To be able to work with them they both need to be publicly accessible.
I am not a Java developer so I will leave the coding aspect to someone else.
I would start by injecting the UserStorage into the class ( in constructor for example ) so you can then use it and you can even change implementations. Use an interface for example so you can have multiple implementations if you need to.
Once you do that, you can use it to retrieve the user from the Service and you can assert against it.
Test 1 : add
Test 2 : update
add more tests for null user, or any other conditions you want to test. I would not mock this, test the real thing instead.
this doesn't involve changing the method's signature, just the way you inject your storage into the class which can be with an IOC framework, if you use one, or simple DI, so not a big change at all.
Upvotes: 0
Reputation: 15018
You mock both the userStorage
and the passed User
.
@RunWith(MockitoJunitRunner.class)
class UserServiceTest {
@InjectMocks private UserService sut;
@Mock private Map<String, User> storage;
@Test
public void testUpdate() {
final String ID = "1";
// setup user passed to method
User user = mock(User.class);
when(user.getId()).thenReturn(ID);
when(user.getName()).thenReturn("name");
// setup user already known to service
User fromStorage = mock(User.class);
when(fromStorage.getId()).thenReturn(ID);
when(storage.get(ID)).thenReturn(fromStorage);
// run method under test
sut.saveOrUpdate(user);
// check update was performed and storage updated
verify(fromStorage).setName("name");
verify(storage).put(ID, fromStorage);
}
}
I'll leave the save
path to you; it's simpler actually.
Upvotes: 2