Hibernate 用mockito模拟限制条件

Hibernate 用mockito模拟限制条件,hibernate,spring,service,mockito,restrictions,Hibernate,Spring,Service,Mockito,Restrictions,我得说我对Mockito和TDD是新手。。我正在努力寻找使用它的理由。。特别是当我发现如下问题时。。 我想在UserService类中测试“RegisterUser”方法。。我正在使用SpringMVC3.0.6、Hibernate、Maven等等 @Override public void registerUser(User user, UserRoles userRole) throws DataAccessException, UserExistingException { che

我得说我对Mockito和TDD是新手。。我正在努力寻找使用它的理由。。特别是当我发现如下问题时。。 我想在UserService类中测试“RegisterUser”方法。。我正在使用SpringMVC3.0.6、Hibernate、Maven等等

@Override
public void registerUser(User user, UserRoles userRole) throws DataAccessException, UserExistingException {
    checkExistingUser(user);
    user.addRole(new Role(userRole));
    String password = encryptPassword(user);
    userRepository.makePersistent(user);
    sendWelcomeEmail(user.getFirstname(), user.getUsername(), password, user.getEmail());
}

private void checkExistingUser(User user) throws UserExistingException {
    List<User> users = userRepository.findByCriteria(Restrictions.or(Restrictions.eq("username", user.getUsername()), Restrictions.eq("email", user.getEmail())));
    if (!CollectionUtils.isEmpty(users)) {
        User userFound = users.get(0);
        List<String> fields = new ArrayList<String>();
        if (userFound.getUsername().equals(user.getUsername())) {
            fields.add("username");
        }
        if (userFound.getEmail().equals(user.getEmail())) {
            fields.add("email");
        }
        throw new UserExistingException(fields);
    }
}
@覆盖
public void registerUser(用户用户、用户角色、用户角色)抛出DataAccessException、UserExistingException{
选中ExistingUser(用户);
addRole(新角色(userRole));
字符串密码=加密密码(用户);
userRepository.makePersistent(用户);
sendWelcomeEmail(user.getFirstname(),user.getUsername(),密码,user.getEmail());
}
私有void checkExistingUser(用户用户)抛出UserExistingException{
List users=userRepository.findByCriteria(Restrictions.or(Restrictions.eq(“username”,user.getUsername()),Restrictions.eq(“email”,user.getEmail()));
如果(!CollectionUtils.isEmpty(用户)){
User userFound=users.get(0);
列表字段=新的ArrayList();
if(userFound.getUsername().equals(user.getUsername())){
字段。添加(“用户名”);
}
if(userFound.getEmail().equals(user.getEmail())){
字段。添加(“电子邮件”);
}
抛出新的UserExistingException(字段);
}
}
现在要测试这些东西,我需要模拟“userRepository.findByCriteria..”,并尝试了以下junit测试

@Test(expected = UserExistingException.class)
public void registerExistingUserTest() throws DataAccessException, UserExistingException {
    User user = new User();
    user.setUsername("gfalco77");
    user.setEmail("Giuseppe.falco@gmail.com");
    List<User> users = new ArrayList<User>();
    users.add(user);


    Mockito.when(userRepository.findByCriteria(Restrictions.or(Restrictions.eq("username", user.getUsername()), Restrictions.eq("email", user.getEmail())))).thenReturn(users);
    userService.registerUser(user, UserRoles.ROLE_USER);
    Mockito.verify(userRepository).makePersistent(user);
}
@Test(预期为UserExistingException.class)
public void registerExistingUserTest()引发DataAccessException、UserExistingException{
用户=新用户();
user.setUsername(“gfalco77”);
user.setEmail(“Giuseppe。falco@gmail.com");
列表用户=新建ArrayList();
用户。添加(用户);
Mockito.when(userRepository.findByCriteria(Restrictions.or)(Restrictions.eq(“username”,user.getUsername()),Restrictions.eq(“email”,user.getEmail()))))。然后返回(users);
userService.registerUser(用户,UserRoles.ROLE\u用户);
Mockito.verify(userRepository).makePersistent(user);
}

但是“用户”列表似乎总是空的。。在上一篇文章中,我读到限制不是同一个对象,也许我必须使用匹配器。。但是怎么做呢?如果我使用匹配器。。使用不同的东西创建测试仍然有效吗?

这不是对您的问题的直接回答,但是您的测试很难编写,因为您的服务类将业务代码与数据访问代码混合在一起。
findByCriteria
调用应该封装到
UserRepository
之类的更高级方法中

List<User> findByNameOrEmail(String name, String email)
列出findByNameOrEmail(字符串名称,字符串电子邮件)
您只需在测试中模拟这个简单的方法,并进行实际的存储库单元测试,测试
findByNameOrEmail
在测试数据库上是否按预期工作


如果UserRepository只公开诸如
findByCriteria
findByQuery
之类的通用方法,那么它就不再是一个真正的存储库,因为创建条件或查询是调用方的责任,而不是存储库的责任。这样做并不会比直接在业务服务中使用Hibernate会话增加太多内容。

这并不能直接回答您的问题,但您的测试很难编写,因为您的服务类将业务代码与数据访问代码混合在一起。
findByCriteria
调用应该封装到
UserRepository
之类的更高级方法中

List<User> findByNameOrEmail(String name, String email)
列出findByNameOrEmail(字符串名称,字符串电子邮件)
您只需在测试中模拟这个简单的方法,并进行实际的存储库单元测试,测试
findByNameOrEmail
在测试数据库上是否按预期工作


如果UserRepository只公开诸如
findByCriteria
findByQuery
之类的通用方法,那么它就不再是一个真正的存储库,因为创建条件或查询是调用方的责任,而不是存储库的责任。这样做没有比直接在业务服务中使用Hibernate会话增加多少。

是的,这很明显。。。现在可以用了。。事实上,UserRepository使用预定义的findbycriteria扩展了GenericyBernateDaoImpl。。因此,在服务中很容易通过标准。应该保护此方法,使其可由子类调用,但不能由外部类调用。它不应该出现在存储库的公共界面中。是的,它很明显。。。现在可以用了。。事实上,UserRepository使用预定义的findbycriteria扩展了GenericyBernateDaoImpl。。因此,在服务中很容易通过标准。应该保护此方法,使其可由子类调用,但不能由外部类调用。它不应该出现在存储库的公共界面中。关于您对Mockito和TDD的感受:我自己对单元测试和TDD非常陌生,但当我开始使用JUnit+Mockito组合时,我几乎立刻爱上了它——这是一种轻松地对代码执行严格测试的好方法。据我所知,TDD的要点是,这样的开发模型旨在确保始终对程序的所有功能进行测试,以便在新更新出现问题时立即知道。这可能不是每个项目的最佳开发模式,但我喜欢将这一理念牢记在心。关于您对Mockito和TDD的感受:我本人对单元测试和TDD非常陌生,但当我开始使用JUnit+Mockito组合时,我几乎立刻爱上了它——这是一种很容易对代码执行严格测试的好方法。据我所知,TDD的要点是,这样的开发模型旨在确保始终对程序的所有功能进行测试,以便在新更新出现问题时立即知道。这可能不是每个项目的最佳开发模式,但我喜欢保持这种哲学