试图模拟一个返回IDataReader的数据服务

本文关键字:IDataReader 返回 数据 服务 一个 模拟 | 更新日期: 2023-09-27 18:13:29

我试图模拟(使用Rhino.Mocks)一个返回IDataReader的DataService。我可以模拟IDataReader (StackOverFlow Q 1792984),但如果我然后Stub出一个数据服务,它返回这个DataReader并将其注入我试图测试它的方法,Stub只返回一个空数据阅读器。

IDataService

public interface IDataService
{
 SqlDataReader ExecuteReader(string cmdText, CommandType commandType);
 <rest of definition ommited
}
单元测试

    [TestMethod]
    public void GetCustomer_Pass()
    {
        //Arrange
        var customer = new Customer()
                       {
                         Id = 1, FirstName = "Patrick",
                         LastName = "Hastings", ProfilePictureURL = ""
                       };
        var mockDataService = MockRepository.GenerateStub<IDataService>();
        var reader = MockRepository.GenerateStub<IDataReader>();
        reader.Stub(x => x.Read()).Repeat.Once().Return(true);
        reader.Stub(x => x.Read()).Return(false);
        reader.Stub(x => x["Id"]).Return(customer.Id);
        reader.Stub(x => x["FirstName"]).Return(customer.FirstName);
        reader.Stub(x => x["LastName"]).Return(customer.LastName);
        reader.Stub(x => x["ProfilePictureURL"]).Return(customer.ProfilePictureURL);
        mockDataService.Stub( s =>
            s.ExecuteReader(string.Format("select FirstName, LastName,ProfilePictureURL from customer where Id = {0}", customer.Id),
                            CommandType.Text))
                            .Return(reader as SqlDataReader);
        var custRepository = new CustomerRepository(mockDataService);
        //Act
        var customer2 = custRepository.GetCustomer(1);
        //Assert
        Assert.AreEqual(customer.FirstName, customer2.FirstName,"FirstName Mismatch");
        Assert.AreEqual(customer.LastName, customer2.LastName, "LastName Mismatch");
    }
方法与

    public CustomerRepository(IDataService dataService) //Constructor
    {
        if (dataService == null) throw new ArgumentNullException("dataService", "dataService cannot be null.");
        this.dataService = dataService;
    }
    public Customer GetCustomer(int id)
    {
        var sql =string.Format("select FirstName, LastName, ProfilePictureURL from customer where Id = {0}",id);
        var dr = dataService.ExecuteReader(sql, CommandType.Text);
        Customer customer ;
        using (dr)
        {
            if (!dr.Read()){return null;}
            customer = new Customer
                         {
                             FirstName = dr["FirstName"].ToString(),
                             LastName = dr["LastName"].ToString(),
                             ProfilePictureURL = dr["ProfilePictureURL"].ToString()
                         };
        }
        return customer;
    }

这个问题,我得到的是,当"dataService。ExecuteReader(sql, CommandType.Text);"应该返回模拟的IDataReader,而不是返回Null -任何指针,我做错了,将不胜感激。

试图模拟一个返回IDataReader的数据服务

第一点:

我相信是因为传入ExecuteReader()方法的参数不同:

设定在期望中:

"select FirstName, LastName,ProfilePictureURL...

在实际调用时传递:(逗号和ProfilePictureURL之间额外空格)

"select FirstName, LastName, ProfilePictureURL...

有时IgnoreArguments()在参数本身无关紧要的情况下非常有用

第二点:

.Return(reader as SqlDataReader);

这是无效的强制转换,因为reader是由RhinoMock创建的模拟对象。

我相信你不需要SqlDataReader类型,所以只需返回reader本身

 .Return(reader)

PS:我还建议将重复的值存储为常量,您也可以将customerId = 1存储为常量,以避免此类可能的问题。