2012-10-09 15 views
0

我有一個需要SqlDataReader對象作爲參數的方法,並且我有測試,我已經嘲笑該對象,並且一切正常。當將SqlDataReader對象傳遞給需要IDataReader接口的方法時丟失數據

但是,現在我需要改變這種方法。它現在應該只調用新的方法,它有一個IDataReader作爲參數,這是一個問題,因爲當我將模擬的SqlDataReader作爲新方法的參數傳遞時,它正在丟失他的數據,我不知道爲什麼。

事情是這樣的:

void method(SqlDataReader mockedObject) 
{ 
    // example property 
    mockedObject.FieldCount; // for example the value is 1; 
    newMethod(mockedObject); 
} 

void newMethod(IDataReader newObject) 
{ 
    // example property 
    newObject.FieldCount // here value is 0; 
} 

我發現,如果我只複製SqlDataReader對象以類型的IDataReader的新變量,數據也將被清除。

事情是這樣的:

void method(SqlDataReader mockedObject) 
{ 
    IDataReader variable = mockedObject; 
} 

的正確代碼:

========================================================================================= 
     [TestMethod()] 
    [DeploymentItem("IICMS.dll")] 
    public void CheckNullableDateTimeTest_SqlDataReader_Valid() 
    { 
     MockRepository mocks = new MockRepository(); 
     SqlDataReader reader = mocks.DynamicMock<SqlDataReader>(); 
     string column = "test"; 
     DateTime? expected = new DateTime(2, 1, 1); 
     Nullable<DateTime> actual; 

     reader.Stub(r => r[column]).Return(expected); 
     reader.Stub(r => r.FieldCount).Return(1); 
     mocks.ReplayAll(); 

     actual = Utility_Accessor.CheckNullableDateTime(reader, column); 
     Assert.AreEqual(expected, actual); 
    } 
====================================================================================== 
     public static DateTime? CheckNullableDateTime(SqlDataReader read, string column) 
    { 
     return GetValue<DateTime?>(read, column, null); 
    } 
====================================================================================== 
public static T GetValue<T>(IDataReader reader, string columnName, T defaultValue) 
    { 
     try 
     { 
      for (int i = 0; i < reader.FieldCount; i++) 
      { 
       if (reader.GetName(i) == columnName) 
       { 
        object value = reader[i]; 
        return Convert.IsDBNull(value) ? defaultValue : (T)value; 
       } 
      } 

      return defaultValue; 
     } 
     catch 
     { 
      return defaultValue; 
     } 
    } 

因此,有代碼,第二和第三種方法在其他的DLL,但它不會對任何事情的影響。對象在RhinoMocks嘲笑)

數據被transfering SqlDataReader對象(讀)到GetValue方法(即段計數等於0,在檢查後失去..方法它具有適當的值= 1)

+0

所以..這是否意味着,如果你調用'FieldCount'兩次(即使在相同的方法),你會得到兩個不同的結果,1然後0? – Patrick

+0

如果不是,'FieldCount'是否被'new'關鍵字覆蓋? – Patrick

+0

請注意,您實際上沒有複製對象,只是轉換引用,因爲'SqlDataReader'沒有任何顯式或隱式轉換運算符。 – casperOne

回答

0

我不能解釋這種變化,但測試方法下面的表格,製作,即所有 對象字段在每個方法(CheckNullString和getValue)aviable:

[TestMethod()] 
    [DeploymentItem("IICMS.dll")] 
    public void CheckNullableDateTimeTest_SqlDataReader_Valid() 
    { 
     MockRepository mocks = new MockRepository(); 
     SqlDataReader reader = mocks.DynamicMock<SqlDataReader>(); 
     IDataReader reader2 = reader; 
     string column = "test"; 
     DateTime? expected = new DateTime(2,1,1); 
     DateTime? actual; 

     reader.Stub(r => r[column]).Return(invalidValue); 
     reader.Stub(r => r[0]).Return(invalidValue); 
     reader.Stub(r => r.FieldCount).Return(1); 
     reader.Stub(r => r.GetName(0)).Return(column); 

     reader2.Stub(r => r[column]).Return(invalidValue); 
     reader2.Stub(r => r[0]).Return(invalidValue); 
     reader2.Stub(r => r.FieldCount).Return(1); 
     reader2.Stub(r => r.GetName(0)).Return(column); 
     mocks.ReplayAll(); 

     actual = Utility_Accessor.CheckNullString(reader, column); 
     Assert.AreEqual(expected, actual); 
    }