创建和提供模拟对象作为参数

时间:2013-02-13 14:51:52

标签: unit-testing interface mocking

我正在尝试重构我的项目,以便我最终开发到一个界面 能够创建模拟对象进行测试,我遇到了麻烦 实施/理解一些概念。我有一个IProducts接口 由Products实施。但显然我希望能够创建一个模拟产品 宾语。

如何让它依赖于界面而不是实现?

public void AddNewProduct()
        {
            IDatabase db = new Database();
            IProducts products = new Products();
            products.addProductsToCache();
        }

即。如何指定此代码以改为使用MockDatabase对象。

2 个答案:

答案 0 :(得分:0)

假设您有要测试的Inventory类。库存依赖于IProducts。所以它不应该关心它使用的Iproducts的实现。唯一重要的是它必须是IP产品的一个实例。在生产中,IP产品的实体将是产品的实例。在测试中,它将是模拟Iproducts的实例。

如果您引入了一个接口(IProducts),但Inventory仍然依赖于具体的Products类,那么您的界面就没用了。它应该只依赖于接口,而不是依赖于实现。

答案 1 :(得分:0)

我将产品传递给方法:

public class YourProductContainerClass
{
    private readonly IDatabase _database;
    private readonly IProducts _products;

    public YourProductContainerClass(
        IDatabase database,
        IProducts products)
    {
        _database = database;
        _products = products;
    }

    public void AddNewProduct(IProduct product)
    {
        products.Add(product);
    }
}

只需2美分。我从不创建interface只是因为我可能会在稍后的时间点编写测试“。我写单元测试,因此我需要一个接口。

  

如果我不是在编写单元测试,那么我也不会创建一个单元测试   接口

为什么不呢?因为出于各种原因,单位测试的需求永远不会得到足够的优先级。然后你有更新你的代码+接口的维护成本,而它没有真正在你的设计中添加一些东西(除了增加LoC的数量)。

所以,imho:习惯在功能之前编写测试。如果由于某种原因你没有看到单元测试的需要,也要考虑是否为该类编写接口是有意义的。

PS:像Resharper这样的工具可以让您在以后的某个时间点轻松提取界面,并将旧版重构为您的界面。这也是TDD的魅力所在,需要很多痛苦。