Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@wkorando
Created March 12, 2019 17:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wkorando/9d1b21a73370ff2f7ef7d98547f8d399 to your computer and use it in GitHub Desktop.
Save wkorando/9d1b21a73370ff2f7ef7d98547f8d399 to your computer and use it in GitHub Desktop.
@ExtendWith(MockitoExtension.class)
public class TestUserService {
@Nested
class TestWithMethodInjection {
@Test
public void testAddNewUserAndAddress(@Mock UserDao userDao, @Mock AddressDao addressDao) {
when(userDao.addNewUser(any())).thenCallRealMethod();
when(addressDao.addNewAddress(any())).thenCallRealMethod();
UserService service = new UserService(userDao, addressDao);
service.addUserAndAddress(new User("name"), new Address("Street", "ST"));
}
@Test
public void testAddUserWithoutName() {
UserService service = new UserService(null, null);
RuntimeException e = assertThrows(RuntimeException.class,
() -> service.addUserAndAddress(new User(null), null));
assertEquals("User name required!", e.getMessage());
}
@Test
public void testRollbackAddUserAddressValidationError(@Mock UserDao userDao) {
when(userDao.addNewUser(any())).thenReturn(1);
UserService service = new UserService(userDao, null);
RuntimeException e = assertThrows(RuntimeException.class,
() -> service.addUserAndAddress(new User("name"), new Address(null, null)));
assertEquals("Address street and state are required!", e.getMessage());
verify(userDao, times(1)).rollbackAddUser(any());
}
@Test
public void testRollbackAddUserErrorSavingAddress(@Mock UserDao userDao, @Mock AddressDao addressDao) {
when(userDao.addNewUser(any())).thenCallRealMethod();
when(addressDao.addNewAddress(any())).thenThrow(new RuntimeException("Error adding address"));
UserService service = new UserService(userDao, addressDao);
assertThrows(RuntimeException.class,
() -> service.addUserAndAddress(new User("name"), new Address("street", "ST")));
verify(userDao, times(1)).rollbackAddUser(any());
}
}
@Nested
class TestWithClassLevelMocks {
@Mock
UserDao userDao;
@Mock
AddressDao addressDao;
@Test
public void testAddNewUserAndAddress() {
when(userDao.addNewUser(any())).thenCallRealMethod();
when(addressDao.addNewAddress(any())).thenCallRealMethod();
UserService service = new UserService(userDao, addressDao);
service.addUserAndAddress(new User("name"), new Address("Street", "ST"));
}
@Test
public void testAddUserWithoutName() {
UserService service = new UserService(null, null);
RuntimeException e = assertThrows(RuntimeException.class,
() -> service.addUserAndAddress(new User(null), null));
assertEquals("User name required!", e.getMessage());
}
@Test
public void testRollbackAddUserAddressValidationError() {
when(userDao.addNewUser(any())).thenReturn(1);
UserService service = new UserService(userDao, null);
RuntimeException e = assertThrows(RuntimeException.class,
() -> service.addUserAndAddress(new User("name"), new Address(null, null)));
assertEquals("Address street and state are required!", e.getMessage());
verify(userDao, times(1)).rollbackAddUser(any());
}
@Test
public void testRollbackAddUserErrorSavingAddress() {
when(userDao.addNewUser(any())).thenCallRealMethod();
when(addressDao.addNewAddress(any())).thenThrow(new RuntimeException("Error adding address"));
UserService service = new UserService(userDao, addressDao);
assertThrows(RuntimeException.class,
() -> service.addUserAndAddress(new User("name"), new Address("street", "ST")));
verify(userDao, times(1)).rollbackAddUser(any());
}
}
}
public class UserService {
private UserDao userDao;
private AddressDao addressDao;
public UserService(UserDao userDao, AddressDao addressDao) {
this.userDao = userDao;
this.addressDao = addressDao;
}
public void addUserAndAddress(User user, Address address) {
if (user.name == null || user.name.isEmpty()) {
throw new RuntimeException("User name required!");
}
userDao.addNewUser(user);
try {
if ((address.street == null || address.street.isEmpty())
|| (address.state == null || address.state.isEmpty())) {
throw new RuntimeException("Address street and state are required!");
}
addressDao.addNewAddress(address);
} catch (Exception e) {
userDao.rollbackAddUser(user);
throw e;
}
}
static class User {
private String name;
public User(String name) {
this.name = name;
}
}
static class Address {
private String street;
private String state;
public Address(String street, String state) {
this.street = street;
this.state = state;
}
}
class UserDao {
public int addNewUser(User user) {
// returns id if user doesn't exist
return 1;
}
public void rollbackAddUser(User user) {
}
}
class AddressDao {
public int addNewAddress(Address address) {
// returns id if address doesn't exist
return 1;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment