Преобразовать IDataReader в SqlDataReader

#c# #nunit #typemock

#c# #nunit #typemock

Вопрос:

Есть ли способ преобразовать IDataReader объект в SqlDataReader объект? Я пытаюсь разорвать зависимость базы данных от одного из API, перехватывая SqlHelper by своим собственным IDataReader (поскольку я не могу создать SqlDataReader объект).

Вот как выглядит мой тестовый пример (и оценка TypeMock):

 Isolate.Fake.StaticMethods(typeof(SqlHelper));
Isolate.WhenCalled(() => SqlHelper.ExecuteReader(string.Empty, CommandType.StoredProcedure, string.Empty))
     .WillReturn(myDataGenerator.ToDataReader() as SqlDataReader);
  

Это компилируется без проблем, но не возвращает никаких строк. Когда я отлаживаю, я вижу, что в нем вообще нет строк. Есть мысли?

Заранее спасибо.

Редактировать (1): поскольку преобразование невозможно, можно ли издеваться над SqlDataReader.

Комментарии:

1. Вы сказали — он успешно компилируется, тогда может возникнуть другая проблема. Пожалуйста, разместите соответствующий код здесь.

Ответ №1:

Нет, вы не можете преобразовать a IDataReader в a SqlDataReader . SqlDataReader является ли a IDataReader — an SqlDataReader может быть преобразован в an, IDataReader а не наоборот.

Ваша реальная проблема в том, что ваш код не был написан для тестирования. Действительно SqlHelper должен быть передан класс экземпляра, который может быть издевательски изменен и возвращает an IDataReader . Или метод или методы, которые вы тестируете, могут быть переработаны, чтобы они не зависели от SqlHelper direclty и take IDataReader .

Однако, если, как я подозреваю, вы не контролируете этот код, вы можете создать свой собственный DataReader, который наследуется от SqlDataReader . Все IDataReader методы являются виртуальными, поэтому вы можете переопределить их самостоятельно.

Комментарии:

1. Вы правы, у меня нет контроля над этим кодом. Я могу создать свой собственный DataReader, но это не поможет существующей огромной базе кода. Это похоже на то, что я делаю первым? Написать тестовые примеры для устаревшего кода, чтобы я мог провести рефакторинг. Или реорганизовать, чтобы я мог писать для него тестовые примеры. В любом случае, большое спасибо.

2. ПРИМЕЧАНИЕ: System.Data.SqlClient.SqlDataReader не может быть унаследован. Вспомогательный класс должен реализовать IDataReader и обернуть экземпляр SqlDataReader. Кроме того, IDataReader находится в интерфейсе, а не в абстрактном классе. Поэтому все члены IDataReader должны быть реализованы в вспомогательном классе.

3. Вы можете: IDataReader reader = (некоторый код для получения результата) SqlDataReader sDataReader = (SqlDataReader) reader;

Ответ №2:

Итак, ваш SqlHelper.Предполагается, что ExecuteReader возвращает SqlDataReader? Почему бы вам просто не использовать свой SqlHelper.ExecuteReader использует IDataReader.

Ответ shf301 был только что опубликован и написан лучше, чем мой, но именно то, что вам нужно знать.