【问题标题】:Mocking a DataReader and getting a Rhino.Mocks.Exceptions.ExpectationViolationException: IDisposable.Dispose(); Expected #0, Actual #1模拟 DataReader 并获得 Rhino.Mocks.Exceptions.ExpectationViolationException: IDisposable.Dispose();预期 #0,实际 #1
【发布时间】:2009-11-24 21:18:19
【问题描述】:

我正在尝试模拟 SqlDataReader

 SqlDataReader reader = mocks.CreateMock<SqlDataReader>();
 Expect.Call(reader.Read()).Return(true).Repeat.Times(1);
 Expect.Call(reader.Read()).Return(false);
 Expect.Call(reader.HasRows).Return(true);
 Expect.Call(reader.Dispose);
 Expect.Call(reader["City"]).Return("Boise");
 Expect.Call(reader["State"]).Return("State");
 Expect.Call(reader["LAT"]).Return(100);
 Expect.Call(reader["LON"]).Return(-100);
 mocks.ReplayAll();

但我不断收到 Rhino.Mocks.Exceptions.ExpectationViolationException: IDisposable.Dispose();我的方法中预期的 #0,实际的 #1 错误

        using (reader)
        {
            if (reader.HasRows)
            {
                while (reader.Read())
                {
                    CityState myCity = new CityState
                       {
                           City = reader["City"].ToString(),
                           State = reader["State"].ToString(),
                           Lat = Convert.ToInt32(reader["LAT"]),
                           Lon = Convert.ToInt32(reader["LON"])
                       };
                    myCities.Add(myCity);
                }                    
            }               
        }

我错过了什么吗?

【问题讨论】:

    标签: c# rhino-mocks


    【解决方案1】:

    我建议您使用 AAA 语法并使用接口 (IDataReader) 而不是具体类型 (SqlDataReader) 重写测试:

    // Arrange
    IDataReader reader = MockRepository.GenerateStub<IDataReader>();
    reader.Stub(x => x.Read()).Repeat.Once().Return(true);
    reader.Stub(x => x.Read()).Return(false);
    reader.Stub(x => x["City"]).Return("Boise");
    reader.Stub(x => x["State"]).Return("State");
    reader.Stub(x => x["LAT"]).Return(100);
    reader.Stub(x => x["LON"]).Return(-100);
    
    // Act
    var myCities = new List<CityState>();
    using (reader)
    {
        while (reader.Read())
        {
            CityState myCity = new CityState
            {
                City = reader["City"].ToString(),
                State = reader["State"].ToString(),
                Lat = Convert.ToInt32(reader["LAT"]),
                Lon = Convert.ToInt32(reader["LON"])
            };
            myCities.Add(myCity);
        }
    }
    
    // Assert
    Assert.AreEqual(1, myCities.Count);
    Assert.AreEqual("Boise", myCities[0].City);
    ...
    

    【讨论】:

    • 我认为既然这个答案被接受了,它一定已经解决了这个问题。但问题仍然存在:为什么它会起作用?我对 IDisposable 有同样的问题(我正在尝试模拟 System.IO.Stream),但我无法弄清楚为什么我的存根 Dispose() 没有被调用。
    • 之所以有效,是因为我们将SqlDataReader 替换为IDataReader 并模拟了IDataReader。在您的情况下,您似乎正在使用抽象类而不是接口。在这种情况下,您需要使用MockRepository.GeneratePartialMock&lt;Stream&gt;() 创建模拟对象并使用streamMock.Expect(x =&gt; x.Dispose()).Throw(new Exception("foo")); 对其定义期望。
    • 为 CityState 添加实现后,此示例是否会在您的计算机上运行?如果没有,你能提供完整的代码让它运行吗?即使在使用 var reader = new Mock() 和 reader.Setup(...) 之后,Moq 4.0.10827 也不适合我。
    猜你喜欢
    • 2014-04-25
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多