如何在IDataReader中设置GetName中的值?

时间:2016-12-08 19:14:38

标签: c# unit-testing mocking rhino-mocks rhino-mocks-3.5

我正在使用Rhino Mocks测试以下方法。

    public static List<string> RetrieveColumnNames(IDataReader reader)
    {
        List<string> columns = null;

        for (int i = 0; i < reader.FieldCount; i++)
        {
            columns.Add(reader.GetName(i));
        }

        return columns;
    }

有这样的事情,但不知道如何继续:

    [TestMethod()]
    public void RetrieveColumnNamesTest()
    {
        //Arrange
        IDataReader reader = MockRepository.GenerateStub<IDataReader>();

        reader.Stub(x => x.FieldCount).Return(2);
        reader.Stub(x => x.name...) // not gonna happen

        //Act
        using (reader)
        {
            List<string> list = RetrieveColumnNames(reader);

            //Assert
            Assert.AreEqual(2, list.Count);
        }

    }

但是如何在方法GetName中安排值进行测试?

2 个答案:

答案 0 :(得分:1)

编写UT的正确方法是:

[TestMethod]
public void TestMethod1()
{
    const string FIRST = "First Name";
    const string SECOND = "Second Name";

    var reader = MockRepository.GenerateStub<IDataReader>();

    reader.Stub(x => x.FieldCount).Return(2);
    reader.Stub(x => x.GetName(0)).Return(FIRST);
    reader.Stub(x => x.GetName(1)).Return(SECOND);

    var actual = RetrieveColumnNames(reader);

    CollectionAssert.AreEquivalent(new [] {FIRST, SECOND}, actual);

}

在这种情况下使用IgnoreArguments().Repeat.Once()是一种不好的做法,主要是因为可能会出现调用排序问题(而且可读性较差......),另一种选择是使用Do方法{ {1}}。

List<string>提供了验证返回值的最佳功能。

顺便说一句;您没有将CollectionAssert初始化为新实例

答案 1 :(得分:0)

您应该只使用Repeat
如果您想要返回相同的值:

reader.Stub(x => x.GetName(0)).IgnoreArguments().Repeat.Any().Return("My Name");

如果您想要返回不同的值:

reader.Stub(x => x.GetName(0)).IgnoreArguments().Repeat.Once().Return("First Name");
reader.Stub(x => x.GetName(0)).IgnoreArguments().Repeat.Once().Return("Second Name");