Testing 您如何模拟您的存储库?

Testing 您如何模拟您的存储库?,testing,repository-pattern,mocking,Testing,Repository Pattern,Mocking,我用Moq来嘲笑我的朋友。然而,最近有人说他们更喜欢创建存储库接口的硬编码测试实现 每种方法的优缺点是什么 编辑:通过Fowler链接澄清了存储库的含义。我假设“存储库”是指一个;如果不是,那么这个答案就不适用了 最近,我一直在对我的DAO进行“内存中”的“模拟”(或测试)实现,基本上是根据传递到模拟构造函数中的数据(列表、映射等)进行操作。通过这种方式,单元测试类可以自由地输入测试所需的任何数据,可以对其进行更改等,而无需强制对“内存中”DAO上运行的所有单元测试进行编码,以使用相同的测试数据

我用Moq来嘲笑我的朋友。然而,最近有人说他们更喜欢创建存储库接口的硬编码测试实现

每种方法的优缺点是什么

编辑:通过Fowler链接澄清了存储库的含义。

我假设“存储库”是指一个;如果不是,那么这个答案就不适用了

最近,我一直在对我的DAO进行“内存中”的“模拟”(或测试)实现,基本上是根据传递到模拟构造函数中的数据(列表、映射等)进行操作。通过这种方式,单元测试类可以自由地输入测试所需的任何数据,可以对其进行更改等,而无需强制对“内存中”DAO上运行的所有单元测试进行编码,以使用相同的测试数据

我在这种方法中看到的另一个优点是,如果我有十几个单元测试需要使用相同的DAO进行测试(例如,注入到被测试的类中),我不需要每次都记住测试数据的所有细节(如果“mock”是硬编码的,您会记住的),那么单元测试将创建测试数据本身。不利的一面是,这意味着每个单元测试必须花费几行代码来创建和连接它的测试数据;但这对我来说是个小缺点

代码示例:

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;
    }
}

我通常会看到两种使用存储库的场景。我要求一些东西,我得到了,或者我要求一些东西,但它不在那里

如果您正在模拟您的存储库,这意味着您的被测系统(SUT)正在使用您的存储库。因此,您通常希望测试当从存储库中为SUT提供对象时,SUT的行为是否正确。你还想测试一下,当你期望得到一些东西而没有,或者不确定你是否会得到一些东西时,它是否能正确地处理这种情况

如果您正在进行集成测试,则硬编码的测试加倍是可以的。比如说,您想保存一个对象,然后将其取回。但这是在测试两个对象之间的交互,而不仅仅是SUT的行为。它们是两种不同的东西。如果您开始编写虚假的存储库,那么您也需要对这些存储库进行单元测试,否则您最终会将代码的成功与失败建立在未经测试的代码之上

这是我对模拟与测试双打的看法。

SCNR:


“你称自己为存储库?我见过容量更大的火柴盒!”

我指的是存储库模式。我编辑了这个问题,并将其链接到马丁·福勒的定义。这是我在阅读这个问题时想到的第一件事:-)谢谢你的回答。它省去了我的努力。