mockito的模拟限制条件
我得说我是Mockito和TDD的新手..我努力寻找使用它的理由..特别是当我发现像下面这样的问题.. 我想喜欢我的UserService类测试“RegisterUser”方法..我使用Spring MVC的3.0.6,休眠时,Maven等..mockito的模拟限制条件
@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("[email protected]");
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);
}
但似乎”用户“列表总是空的。在之前的文章中,我读到限制不是同一个对象,也许我必须使用Matchers ..但是如何?如果我使用匹配器..它仍然有效创建一个不同的测试?
这不是对您的问题的直接回答,但是您的测试很难编写,因为您的服务类将业务代码与数据访问代码混合在一起。该findByCriteria
调用应该被封装到的UserRepository
更高级别的方法类似
List<User> findByNameOrEmail(String name, String email)
你只在你的测试来模拟这种简单的方法,使实际存储库的单元测试,测试的findByNameOrEmail
作品预计在测试数据库上。
如果您的UserRepository仅公开诸如findByCriteria
或findByQuery
等通用方法,那么它不再是真正的存储库,因为条件或查询的创建是由调用者而不是存储库负责的。这样做并没有比直接在业务服务中使用Hibernate会话添加更多的功能。
是的,它是那么明显......现在的工作。该事实是,UserRepository正在伸出GenericHibernateDaoImpl与预定义的findbycriteria ..所以很容易在通过标准.. – Gfalco
这个方法应该加以保护,以服务使其可以由子类调用,但不能由外部类调用。它不应该在存储库的公共界面中。 –
在你的感情走向的Mockito和TDD:我是相当新的单元测试和TDD自己,但我爱上了JUnit +的Mockito组合几乎是瞬间下降,当我开始使用它 - 这是很容易地进行严格的好方法测试你的代码。我的理解是TDD的一点是,这样的发展模式是为了确保总有您的所有程序的功能测试,让你马上知道你的新的更新打破的东西。这可能不是每个项目的最佳开发模式,但我喜欢牢记这一理念。 –