This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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()); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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