答案 0 :(得分:6)
我通常会看到两个带存储库的方案。我要求一些东西,我得到它,或者我要求一些东西,它就不存在了。
如果您正在模拟您的存储库,那意味着您正在使用您的存储库来测试系统(SUT)。因此,您通常希望在从存储库中获取对象时测试您的SUT是否正常运行。并且你还想测试它是否能够正确地处理这种情况,当你期望得到回报而不是,或者不确定你是否会得到回报。
如果您正在进行集成测试,则硬编码测试双打是可以的。比如说,你想要保存一个对象,然后把它取回来。但这是测试两个对象在一起的交互,而不仅仅是SUT的行为。他们是两个不同的东西。如果您开始编写假存储库,那么您也需要进行单元测试,否则您最终会将代码的成功与失败基于未经测试的代码。
这是我对Mocking vs. Test Doubles的看法。
答案 1 :(得分:6)
SCNR:
“你称自己为存储库?我见过火柴盒的容量更大!”
答案 2 :(得分:0)
我认为“存储库”是指DAO;如果没有,那么这个答案将不适用。
最近我一直在制作“内存”我的DAO的“模拟”(或测试)实现,它基本上是通过传递给mock的构造函数的数据(List,Map等)来操作的。通过这种方式,单元测试类可以自由地输入测试所需的任何数据,可以更改它等,而不必强制对“内存”DAO中运行的所有单元测试进行编码以使用相同的测试数据。
我在这种方法中看到的一个优点是,如果我有十几个单元测试需要使用相同的DAO进行测试(例如注入被测试的类),我不需要记住每次测试数据的所有细节(如果“模拟”是硬编码的那样) - 单元测试自己创建测试数据。在缺点方面,这意味着每个单元测试必须花费几行来创建和连接它的测试数据;但这对我来说是一个小小的缺点。
代码示例:
public interface UserDao {
User getUser(int userid);
User getUser(String login);
}
public class InMemoryUserDao implements UserDao {
private List users;
public InMemoryUserDao(List users) {
this.users = users;
}
public User getUser(int userid) {
for (Iterator it = users.iterator(); it.hasNext();) {
User user = (User) it.next();
if (userid == user.getId()) {
return user;
}
}
return null;
}
public User getUser(String login) {
for (Iterator it = users.iterator(); it.hasNext();) {
User user = (User) it.next();
if (login.equals(user.getLogin())) {
return user;
}
}
return null;
}
}