2011-09-03 99 views
1

未能在下面的測試中,嘲笑DataReader的返回所希望的值是第一次,但然後返回當指標應爲1。模擬DataReader的上第二呼叫

我是否濫用的DataReader或犀牛存根的值相同句法?什麼是修復?

乾杯,
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

你是不是嘲笑由NHibernate的叫一切。這大致就是NHibernate的做一個讀者:犀牛產生

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

存根會響應這兩個GetOrdinal調用返回0,莫非這就是爲什麼它會返回June1兩次。您可以嘗試通過嘲笑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); 

但它可能是值得重新考慮你是否真的需要單元測試用戶類型。除了調用NHibernate之外,它沒有太多的責任。單元測試這個類需要你模擬你不擁有的類型(MS IDataReader)。更糟糕的是,這個模擬被另一個第三方(NHibernate)使用。基本上你需要看看NHibernate的源代碼(這是我所做的)來創建一個正確的存根。看看this article。它涉及更多的細節,爲什麼你應該避免嘲笑你不擁有的類型。使用in-memory sqlite database,您可能最好使用積分測試此課程。

+0

@Dimitry。謝謝你的一個很好的答案,這是有效的!我認爲單元測試在這裏是有道理的,因爲重寫方法確實包含了大量的邏輯,它們更容易孤立地進行測試,但我同意你指出的困難。乾杯 – Berryl

相關問題