【问题标题】:Mock Restrictions criteria with mockito使用 mockito 模拟限制标准
【发布时间】:2011-12-12 22:43:33
【问题描述】:

我得说我是 Mockito 和 TDD 的新手。我正在努力寻找使用它的理由。尤其是当我发现类似以下问题时。 我想在我的 UserService 类中测试一个“RegisterUser”方法。我正在使用 spring mvc 3.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);
    }
}

现在要测试这些东西,我需要模拟“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);
}

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

【问题讨论】:

  • 关于您对 Mockito 和 TDD 的感受:我自己对单元测试和 TDD 还很陌生,但是当我开始使用 JUnit+Mockito 组合时,我几乎立刻就爱上了它——它很棒轻松对代码执行严格测试的方法。我理解 TDD 的意义在于,这样的开发模型旨在确保始终对您的程序的所有功能进行测试,因此您可以立即知道您的新更新何时会破坏某些东西。它可能不是每个项目的最佳开发模型,但我喜欢牢记这一理念。

标签: hibernate spring service mockito restrictions


【解决方案1】:

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

List<User> findByNameOrEmail(String name, String email)

您只需在测试中模拟这个简单的方法,并进行实际的存储库单元测试,测试findByNameOrEmail 在测试数据库上是否按预期工作。

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

【讨论】:

  • 是的,这很明显......它现在可以工作了......事实上,UserRepository 正在扩展一个带有预定义 findbycriteria 的 GenericHibernateDaoImpl ......所以在服务中很容易通过标准......
  • 这个方法应该受到保护,使它可以被子类调用,但不能被外部类调用。它不应该在存储库的公共界面中。
猜你喜欢
  • 1970-01-01
  • 2018-04-03
  • 1970-01-01
  • 1970-01-01
  • 2013-12-30
  • 2012-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多