Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有模拟DAL的单元测试方法,但底层方法调用不同的(实际)DAL_C#_Unit Testing_Inversion Of Control_Design Patterns - Fatal编程技术网

C# 具有模拟DAL的单元测试方法,但底层方法调用不同的(实际)DAL

C# 具有模拟DAL的单元测试方法,但底层方法调用不同的(实际)DAL,c#,unit-testing,inversion-of-control,design-patterns,C#,Unit Testing,Inversion Of Control,Design Patterns,我正试图在我当前的项目中实现单元测试。在那之后,我将开始在这个项目中进一步使用TDD进行开发。 昨天我开始做一些测试,但并不像理论书上看起来那么容易 目前,我正在为一个特定的场景而挣扎,我知道过去肯定也有其他人与之合作过 一些背景资料。 我在类AddProduct中有一个名为Add()的方法。当一个新对象被传递到Add方法时,必须首先创建一个新项,因此我必须首先调用AddItem类的Add()方法。 所有这些代码都存在于业务层中。当然,真正的添加发生在DAL中,它是从我的AddProduct和A

我正试图在我当前的项目中实现单元测试。在那之后,我将开始在这个项目中进一步使用TDD进行开发。 昨天我开始做一些测试,但并不像理论书上看起来那么容易

目前,我正在为一个特定的场景而挣扎,我知道过去肯定也有其他人与之合作过

一些背景资料。 我在类
AddProduct
中有一个名为
Add()
的方法。当一个新对象被传递到
Add
方法时,必须首先创建一个新项,因此我必须首先调用
AddItem
类的
Add()
方法。 所有这些代码都存在于业务层中。当然,真正的添加发生在DAL中,它是从我的
AddProduct
AddItem
类中调用的

为了得到一个想法,这是我到目前为止得到的:

public class AddProduct : Product<IDataAccessAdd<Entities.Product>>, IBusinessAdd<Entities.Product>
{
    private readonly Business.IBusinessAdd<Entities.Item> _addItem;
    public AddProduct() : base(new DataAccess.AddProduct())
    {
        _addItem = new AddItem();
    }
        public AddProduct(DataAccess.IDataAccessAdd<Entities.Product> dal, Business.IBusinessAdd<Entities.Item> itemBl) : base(dal)
    {
        _addItem = itemBl;
    }

    private Entities.Product _newProduct;
    public bool Add(ref Product product, string user)
    {
        bool isAdded = false;
        _newProduct = product;
        if(AddNewItem(user))
        {
            isAdded = Dal.Add(product);
        }
        return isAdded;
    }

    private bool AddNewItem(string user)
    {
        var newItem = new Item();
        bool isAdded = _addItem.Add(ref newItem, user);
        _newProduct.Item = newItem;
        return isAdded;
    }
}
还有像这样的AddNewItem方法(或类似的方法):

但是在执行此操作时,在
AddNewItem
方法中执行的代码使用了“real”DAL,我不希望在单元测试中使用它。我通过向构造函数添加一个新参数解决了这个问题,它还可以为
Business.Item
类创建一个模拟DAL。然而,我不认为这是一条路要走。 理论上,您可以得到一个包含20个参数的构造函数,所有参数都用于单元测试。不太好看

我的一位同事告诉我,这可能可以使用工厂方法设计模式来解决,但他不确定这是否是最佳选择。 由于我从未使用过工厂方法设计模式,所以当单元测试对我来说也是新的时候,我觉得实现它并不舒服


还有什么我可以尝试的建议吗?

这里有两种方法可以使用

  • 设置专门用于测试的IOC容器。在此容器中,您可以将dal服务配置为测试或模拟dal服务

  • 手动连接您的类。在这种情况下,您将显式调用AddProduct构造函数并通过测试或模拟DAL服务


  • 这背后的基本原理是依赖注入允许您创建一个沙箱来隔离和测试代码的特定部分。上面的选项创建了沙箱。

    这里有两种方法可以使用

  • 设置专门用于测试的IOC容器。在此容器中,您可以将dal服务配置为测试或模拟dal服务

  • 手动连接您的类。在这种情况下,您将显式调用AddProduct构造函数并通过测试或模拟DAL服务


  • 这背后的基本原理是依赖注入允许您创建一个沙箱来隔离和测试代码的特定部分。上面的选项创建了沙箱。

    向现有代码添加单元测试总是比从头开始更难。一本有用的书是《有效地使用遗留代码》(WorkingeffectivewithLegacy Code)(),这本书是关于向现有系统添加单元测试的(尽管你从书名中不知道)。谢谢你的建议。事实上,我现在正在读这本书。这对于学习如何处理某些案例是非常好的。在这本书之前我读过的书是《干净的代码》,如果你想开始使用单元测试(以及更好的代码),这本书也是一本不错的书。一本有用的书是《有效地使用遗留代码》(WorkingeffectivewithLegacy Code)(),这本书是关于向现有系统添加单元测试的(尽管你从书名中不知道)。谢谢你的建议。事实上,我现在正在读这本书。这对于学习如何处理某些案例是非常好的。在这本书之前我读过的书是《干净的代码》,如果你想开始使用单元测试(和更好的代码),这也是一本不错的书。嗯,IoC容器看起来不错,不过如果我理解正确的话,它可以掩饰问题。这个问题:这个页面这个链接:你对它的理解真的很有帮助。嗯,一个IoC容器看起来很不错,不过如果我理解正确的话,它可以掩饰这个问题。这个问题:和这个页面这个链接:真的很有帮助,了解它更好一点。
    public AddProduct() : base(new DataAccess.AddProduct())
    {
    }
    public AddProduct(DataAccess.IDataAccessAdd<Entities.Product> dal) : base(dal)
    {
    }
    
    private bool AddNewItem(string user)
    {
        var newItem = new Item();
        var addItem = new Business.AddItem();
        bool isAdded = addItem.Add(ref newItem, user);
        _newProduct.Item = newItem;
        return isAdded;
    }