As I flesh out the business logic for this application I am presented with another problem. I have put logic in place to handle adding users with duplicate usernames, screen names, or email addresses. I check this by adding the business logic to the domain facade similar to jpetstore's PetStoreImpl.
But when I attempt to unit test (using AbstractTransactionalDataSourceSpringContextTests) Hibernate seems to not correctly handle the multiple calls to check for duplicates.
The DuplicateUsernameException gets thrown when running the testUpdateUser().
When debugging in Eclipse I have noticed that this call
Code:
User usernameUser = this.userDAO.findUserByUsername(user.getUsername());
returns the correct user but with an incorrect id. Hence the next check
Code:
if (usernameUser != null && usernameUser.getId() != user.getId())
throw new DuplicateUsernameException(user.getUsername());
throws the exception because it thinks there is already another user with this username.
Any ideas? How are others testing there domain logic?
Snip of Biz Facade
Code:
public class BizImpl implements BizFacade {
private UserDAO userDAO;
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
public User updateUser(User user) {
// Check for duplicate username
User usernameUser = this.userDAO.findUserByUsername(user.getUsername());
if (usernameUser != null && usernameUser.getId() != user.getId())
throw new DuplicateUsernameException(user.getUsername());
// Check for duplicate screen name
User screenNameUser = this.userDAO.findUserByScreenName(user.getScreenName());
if (screenNameUser != null && screenNameUser.getId() != user.getId())
throw new DuplicateScreenNameException(user.getScreenName());
// Check for duplicate email address
User emailUser = this.userDAO.findUserByEmail(user.getEmailAddress());
if (emailUser != null && emailUser.getId() != user.getId())
throw new DuplicateEmailAddressException(user.getEmailAddress());
return this.userDAO.update(user);
}
}
Snip of relevant test case
Code:
public class BaseUserIntegrationTest extends AbstractTransactionalDataSourceSpringContextTests {
protected BizFacade bizImpl;
protected AbstractTestDatabaseHelper dbHelper;
public void setBizImpl(BizFacade bizImpl) {
this.bizImpl = bizImpl;
}
public void setDbHelper(AbstractTestDatabaseHelper dbHelper) {
this.dbHelper = dbHelper;
}
protected void onSetUpInTransaction() throws Exception {
this.dbHelper.setJdbcTemplate(this.jdbcTemplate);
}
protected void onTearDownInTransaction() throws Exception {
super.onTearDownInTransaction();
clearCache();
}
private void clearCache() {
SessionFactory sessionFactory = (SessionFactory)applicationContext.getBean("sessionFactory");
sessionFactory.evict(User.class);
}
public void testUpdateUser() {
// Add user
long userID = dbHelper.addUser("btucker", "little_one1", "big tucker", "forget@about.it");
// Update user with new username, password, and screen name
User userToUpdate = this.bizImpl.findUserByID(userID);
userToUpdate.setUsername("queen_bee");
userToUpdate.setPassword("4509890");
userToUpdate.setScreenName("yakami");
userToUpdate.setEmailAddress("iamtheman@forget_about.it");
this.bizImpl.updateUser(userToUpdate);
// Assert that user updated in database
User updatedUser = this.bizImpl.findUserByID(userToUpdate.getId());
Assert.assertEquals("Username not updated", updatedUser.getUsername(), "queen_bee");
Assert.assertEquals("Password not updated", updatedUser.getPassword(), "4509890");
Assert.assertEquals("Screen name not updated", updatedUser.getScreenName(), "yakami");
Assert.assertEquals("Email address not updated", updatedUser.getEmailAddress(), "iamtheman@forget_about.it");
}
}
Snip of Hibernate DAO
Code:
public class HibernateUserDAO extends GenericHibernateDAO<User, Long> implements UserDAO {
public HibernateUserDAO() {
super(User.class);
}
public User findUserByUsername(String username) throws DataAccessException {
Query q = this.getSession().createQuery("from User u where u.username=:username");
q.setParameter("username", username);
return (User) q.uniqueResult();
}
}