【问题标题】:Is it possible to mock a local-initialized object with MOQ?是否可以使用 MOQ 模拟本地初始化的对象?
【发布时间】:2013-12-01 14:41:13
【问题描述】:

我有以下代码:

public class DB
{
    public virtual int GetNumbers()
    {
        return 42;
    }
}

public interface ITestable
{
    int TestMethod();
}

public class Testable : ITestable
{
    public int TestMethod()
    {
        DB db = new DB();
        return db.GetNumbers() + 20;
    }
}

现在我想使用 MOQ 创建一个模拟数据库,这样每次创建和初始化数据库时(就像在 Testable.TestMethod 中一样),它都会使用模拟的数据库实例。

例如,也许我可以设置 DB Mock,这样对于所有 DB 的实例,当调用 GetNumbers 方法时,它将返回 12 而不是 42。这样 Testable.TestMethod 将返回 32,而不是 62。

我想知道起订量是否可以处理这种情况?其实我知道 TypeMock Isolator 和 Microsoft Fakes Framework 可以做到这一点。而且我也不喜欢采用“测试驱动开发”方法(这意味着我需要调整我的设计)。

【问题讨论】:

  • 你想要依赖注入

标签: c# unit-testing tdd moq


【解决方案1】:

不,你不能用 Moq nor any other dynamic proxy based framework 模拟它。您不需要 TDD(这与您的问题无关) - 您应该查看的是 Dependency Injection(这将改变您的设计)。

您的代码的可测试版本需要factoryDB 对象的抽象,例如:

public class Testable : ITestable
{
    private readonly Func<IDb> dbFactory;  

    public class Testable(Func<IDb> dbFactory)
    {
        this.dbFactory = dbFactory;
    }


    public int TestMethod()
    {
        var db = dbFactory();
        return db.GetNumbers() + 20;
    }
}

对于 Moq,这是解决此类问题的最常见方法。如果您想坚持当前的设计,则必须使用付费工具。

【讨论】:

  • 是的,你是对的。实际上我找不到最小起订量可以处理这种情况的方法。所以这就是为什么我在这里提出一个问题。老实说,我不想改变我的设计。至于某些情况下,我需要根据一些配置在调用者类中初始化实用程序对象,我认为没有必要作为依赖项传入。无论如何,感谢您回答并指出正确的方法。 :)
猜你喜欢
  • 1970-01-01
  • 2021-05-28
  • 2013-03-07
  • 1970-01-01
  • 2022-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多