代码之家  ›  专栏  ›  技术社区  ›  dretzlaff17

如何模拟数据阅读器到单元测试DAL

c#
  •  6
  • dretzlaff17  · 技术社区  · 15 年前

    我的数据访问层中有一个方法可以执行映射。方法接受一个DataReader,并将数据映射到适当的域对象属性。有没有一种好方法可以模拟数据阅读器,这样我就可以在不触及物理数据库的情况下对映射方法执行单元测试?

    3 回复  |  直到 10 年前
        1
  •  11
  •   Jay    15 年前

    幸运的是你, DataReader 实现 IDataReader 接口。

    而不是依赖 数据存储器 在代码中,使用 偶像崇拜者 . 然后,在您的测试中,您可以替换返回虚拟数据的您自己的实现,或者使用类似这样的模拟框架 Rhino.Mocks 或者类似于创建存根并分配返回值。

    取决于你是如何“得到”的 数据存储器 在代码中,您可能需要进行一些重构。您需要的是在构造函数(首选)中或通过属性“注入”这样的外部依赖项,以便类的使用者可以替换 偶像崇拜者 . (这种替换也是将参数/属性声明为抽象而不是具体类型的原因。)这就是 Dependency Injection 一种形式 Inversion of Control .

        2
  •  3
  •   Darin Dimitrov    15 年前

    是的,不要使用 DataReader 但是 IDataReader IDataRecord ,然后模仿你想要的任何东西。

        3
  •  3
  •   param3216    10 年前

    如果要模拟IDataReader以返回记录列表,可以创建实现IDataReader的类并重写其某些方法(如read()和indexer)。此外,您还需要一个变量来记录当前行,一个变量来保存列表值。下面是执行此操作的示例代码:

    public class MockDataReader : IDataReader
    {
        private int _rowCounter = 0;
        private List<Dictionary<string,object>> _records = new List<Dictionary<string,object>>();
    
        public MockDataReader(List<Dictionary<string,object>> records)
        {
            _records = records;
        }
    
        public bool Read()
        {
            _rowCounter++;
            if (_rowCounter < _records.Count) return true;
            return false;
        }
    
        public object this[string name]
        {
            get { return _records[_rowCounter][name]; }
        }
    }
    

    然后,要使用这个类,可以使用以下代码:

    var itemsList = new List<Dictionary<string, object>>();
    for (int i = 0; i < 5; i++)
    {
        var num = i + 1;
        var items = new Dictionary<string, object>();
        items.Add("Id", num);
        items.Add("FirstName", "MyFirstName" + num);
        items.Add("LastName", "MyLastName" + num);
        itemsList.Add(items);
    }
    
    
    var result = new MockDataReader(itemsList); 
    

    不是完全证明的方法,但有效。希望有帮助:)