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

나는 내가 단지 형 IDataReader에 새로운 변수로하여 SqlDataReader 개체를 복사하고있어 경우, 데이터는 삭제되는 것을 관찰했다. 이 같은

뭔가 :

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에 조롱하는, 방법이 적절한 값을 갖습니다 ..

데이터 체크 (즉, FieldCount는 0 일을 getValue 메소드하여 SqlDataReader 개체 (읽기)를 transfering 후 잃어 가고있다) = 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); 
    } 
관련 문제