2012-10-09 14 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); 
    }