c# - 无法让 Rhino Mock 迭代 DataReader

标签 c# unit-testing rhino-mocks rhino datareader

我正在尝试使用 RhinoMocks 模拟 IDataReader,但我很难让它迭代 DataRows。这是我到目前为止所做的:

[TestFixture]
public sealed class TestStubbedDataReader
{
    private int currentRowIdx;  //The current position in the datareader
    private bool notAtEnd;      //Return value of the Reader.Read method
    private int countOfRows;    //Count of rows in the dataReader

    private IList<IDataRecord> rows;    //The datarecords that the reader should iterate through


    [Test]
    public void TestDataReader()
    {

        //Mock the reader 
        MockRepository mockRepository = new MockRepository();
        IDataReader reader = mockRepository.Stub<IDataReader>();

        //Build a list of IDataRecords to for the datareader with two records. 
        //It mocks a simple table with a Int32 Id field and a string Name field.             
        rows = new List<IDataRecord>()
                              {
                                  new RowBuilder().WithValues(1, "AAA").Build(),
                                  new RowBuilder().WithValues(1, "BBB").Build()
                              };

        //Initializing variables for iteration
        currentRowIdx = 0;
        notAtEnd = true;
        countOfRows = rows.Count;

        //NOTE: It is probably here I am doing something wrong!!
        //Seting  up results for for reading the fields of the current record. 
        SetupResult.For(reader.GetInt32(0)).Return(rows[currentRowIdx].GetInt32(0));
        SetupResult.For(reader.GetString(1)).Return(rows[currentRowIdx].GetString(1));

        //Seting up returnValue for Reader.Read(). 
        //Call back increases the currentRowIdx or sets notAtEnd flag to False
        SetupResult.For(reader.Read()).Return(notAtEnd).Callback(new CallBackDelegate(MoveToNextRecord));

        mockRepository.ReplayAll();


        Int32 previousId = -1; 
        string previousName = string.Empty; 

        //Here I iterate through the DataReader.  
        while (reader.Read())
        {
            Console.WriteLine("Read ID:  " + reader.GetInt32(0) + " Name: " + reader.GetString(1));
            //dataValueObjects.Add(new ToxDataValueObject(reader));
            Console.WriteLine("Read");

            Assert.That(reader.GetInt32(0), !Is.EqualTo(previousId), "Id is the same as in the previous record");
            Assert.That(reader.GetString(1), !Is.EqualTo(previousName), "Name is the same as in the previous record");

            previousId = reader.GetInt32(0);
            previousName= reader.GetString(1); 

        }

    }


    public delegate bool CallBackDelegate(); 


    private bool MoveToNextRecord()
    {
        if (currentRowIdx<= countOfRows) //Not at the end yet; increas
        {
            currentRowIdx++; 
        }
        else                            //At the end. Next time, Reader.Read should return False
        {
            notAtEnd = false;
        }

        return notAtEnd; 
    }



}


//Builder for DataRows
internal class RowBuilder
{
    private MockRepository _mockRepository;
    private IDataRecord _dataRecord;

    public RowBuilder()
    {
        //Initialise and create stubbed datarecord. 
        _mockRepository = new MockRepository();
        _dataRecord = _mockRepository.Stub<IDataRecord>();
    }

    //Set return values, and return builder
    public RowBuilder WithValues(int id, string name)
    {
        SetupResult.For(_dataRecord.GetInt32(0)).Return(id);
        SetupResult.For(_dataRecord.GetString(1)).Return(name);
        return this;
    }


    //Return the mocked DataRow
    public IDataRecord Build()
    {
        _mockRepository.ReplayAll();
        return _dataRecord; 
    }
}

读取器按预期循环两次,但第二次迭代的返回值与第一次相同。应该做什么???

最佳答案

我的建议:避免模拟具有潜在复杂(和隐藏)行为的组件。相反,以不太通用的方式定义一个适合您需求的适配器接口(interface),并在代码中使用它而不是 IDataReader。然后模拟该接口(interface),这应该是一个简单得多的任务。

在生产代码中,定义并使用与真实 IDataReader 配合使用的适配器接口(interface)的实现。

关于c# - 无法让 Rhino Mock 迭代 DataReader,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6108135/

相关文章:

c# - 在 OData 中提供 DateTime 值

c# - Windows Phone 7 - 在页面之间传递值

c# - 脚手架 EntityFramework 6 无法将类型为 'System.Data.Entity.Core.Objects.ObjectContext' 的对象转换为 'System.Data.Objects.ObjectContext'

visual-studio-2010 - 如何在没有 Visual Studio 的情况下使用 MSTest?

javascript - 谷歌日历 sinon stub 似乎不起作用

.net - 犀牛模拟 : AAA test syntax without static MockRepository methods?

rhino-mocks - 我可以让Rhino MocksGenerateStub或GenerateMock每次都返回一个新类型吗?

c# - 将基于 mfc 对话框的 Windows 应用程序转换为基于 Web

c# - 为什么 Rhino Mocks 会在 stub 上出错,但不会在与模拟完全相同的东西上出错?

unit-testing - 为什么 TypeError : axios. create 不是函数?测试axios GET时