Мокинг над DataReader и получение исключения Rhino.Mocks.Exceptions.ExpectationViolationException: IDisposable.Dispose (); Ожидаемый # 0, Фактический # 1

Я пытаюсь издеваться над 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);
                }                    
            }               
        }

я что-то упускаю?


person Bob The Janitor    schedule 24.11.2009    source источник


Ответы (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);
...
person Darin Dimitrov    schedule 24.11.2009
comment
Я предполагаю, что, поскольку этот ответ был принят, значит, проблема была решена. Но остается вопрос: почему это сработало? У меня такая же проблема с IDisposable (я пытаюсь издеваться над System.IO.Stream), и я не могу понять, почему мой заглушенный Dispose () не вызывается. - person Bruce Johnston; 26.09.2010
comment
Это работает, потому что мы заменили SqlDataReader на IDataReader и высмеяли этот IDataReader. В вашем случае кажется, что вы работаете с абстрактным классом вместо интерфейса. В этом случае вам нужно создать фиктивный объект с MockRepository.GeneratePartialMock<Stream>() и определить ожидания для него с помощью streamMock.Expect(x => x.Dispose()).Throw(new Exception("foo"));. - person Darin Dimitrov; 26.09.2010
comment
Будет ли этот пример работать на вашем компьютере после добавления реализации для CityState? Если нет, не могли бы вы предоставить полный код, чтобы он работал? Это не для меня с Moq 4.0.10827 даже после использования var reader = new Mock ‹IDataReader› () и reader.Setup (...). - person Lernkurve; 12.01.2011