Ошибка ложного чтения данных при втором вызове - PullRequest
1 голос
/ 03 сентября 2011

В тесте, приведенном ниже, макетированный носитель данных возвращает требуемое значение в первый раз, но затем возвращает то же значение, когда индекс должен быть равен 1.

Я неправильно использую синтаксис dataReader или Rhino? Что за исправление?

Приветствия
Berryl

проваленный тест

[Test]
public void NullSafeGet_GetsBothProperties()
{
    var sessionImplementor = MockRepository.GenerateStub<ISessionImplementor>();
    var userType = new DateRangeUserType();

    var reader = MockRepository.GenerateStub<IDataReader>();           
    var start = new DateTime(2011, 6, 1);
    var end = new DateTime(2011, 7, 1);
    reader.Stub(x => x[0]).Return(start);
    reader.Stub(x => x[1]).Return(end);    ***<==== returns Jun 1 instead of Jul1

    var result = userType.NullSafeGet(reader, userType.PropertyNames, sessionImplementor, null);
    Assert.That(result, Is.EqualTo(new DateRange(start, end, DateRange.MaxSupportedPrecision)));

}
Expected: <6/1/2011 12:00 AM - 7/1/2011 12:00 AM>
But was:  <6/1/2011 12:00 AM - 6/1/2011 12:00 AM>

SUT (метод NHib CompositeUserType)

public override object NullSafeGet(IDataReader dr, string[] names, ISessionImplementor session, object owner) {
    if (dr == null) return null;

    var foundStart = (DateTime)NHibernateUtil.DateTime.NullSafeGet(dr, names[0], session, owner);
    var foundEnd = (DateTime)NHibernateUtil.DateTime.NullSafeGet(dr, names[1], session, owner);

    var precision = DateRange.MaxSupportedPrecision;
    var startDp = _getDatePoint(foundStart, precision);
    var endDp = _getDatePoint(foundEnd, precision);

    return new DateRange(startDp, endDp, precision);
}

1 Ответ

1 голос
/ 04 сентября 2011

Вы не издеваетесь над всем, что называется NHibernate.Это примерно то, что NHibernate делает с читателем:

...
int index = reader.GetOrdinal(name);
...
if (reader.IsDBNull(index)) {
    return null;
} else {
    ...
    val = rs[index];
    ...
}

Заглушка, сгенерированная Rhino, вернет 0 в ответ на оба вызова GetOrdinal, и именно поэтому она вернет июнь1 оба раза.Вы можете попытаться исправить это, издеваясь над GetOrdinal и индексатором.Например:

var reader = MockRepository.GenerateStub<IDataReader>();
var start = new DateTime(2011, 6, 1);
var end = new DateTime(2011, 7, 1);

reader.Stub(x => x.GetOrdinal(userType.PropertyNames[0])).Return(0);
reader.Stub(x => x.GetOrdinal(userType.PropertyNames[1])).Return(1);

reader.Stub(x => x[0]).Return(start);
reader.Stub(x => x[1]).Return(end);

Но, возможно, стоит пересмотреть, действительно ли вам нужно unit test UserType.Он не несет большой ответственности, кроме вызова NHibernate.Модульное тестирование этого класса требует, чтобы вы имитировали тип, который вам не принадлежит (MS IDataReader).Еще хуже то, что эта насмешка используется другой третьей стороной (NHibernate).По сути, вам нужно взглянуть на исходный код NHibernate (что я и сделал), чтобы создать правильную заглушку.Взгляните на эту статью .В нем много подробностей о том, почему вы должны избегать насмешливых типов, которые вам не принадлежат.Возможно, вам лучше написать для этого класса интеграционный тест с использованием базы данных sqlite в памяти .

...