Как мне протестировать метод, заполняющий список из DataReader?

StackOverflow https://stackoverflow.com/questions/29980

  •  09-06-2019
  •  | 
  •  

Вопрос

Итак, я работаю над устаревшим кодом, который требует больших ручных операций с базой данных.Я пытаюсь сохранить некое подобие качества, поэтому максимально использую TDD.

Код, над которым я работаю, необходимо заполнить, скажем, List<Foo> из DataReader, который возвращает все поля, необходимые для функционирования Foo.Однако, если я хочу убедиться, что код действительно возвращает один элемент списка на одну строку базы данных, я пишу тестовый код, который выглядит примерно так:

Expect.Call(reader.Read()).Return(true);
Expect.Call(reader["foo_id"]).Return((long) 1);
// ....
Expect.Call(reader.Read()).Return(true);
Expect.Call(reader["foo_id"]).Return((long) 2);
// ....
Expect.Call(reader.Read()).Return(false);

Это довольно утомительно и к тому же довольно легко сломается.

Как мне следует подойти к этой проблеме, чтобы результатом не стала огромная путаница хрупких тестов?

Кстати, сейчас я использую для этого Rhino.Mocks, но могу изменить его, если результат будет достаточно убедительным.При условии, что альтернативой не является TypeMock, потому что их лицензионное соглашение было слишком пугающим, на мой вкус, в последний раз, когда я проверял.

Редактировать:В настоящее время я также ограничен C # 2.

Это было полезно?

Решение

Чтобы сделать это менее утомительным, вам нужно будет инкапсулировать/реорганизовать сопоставление между DataReader и объектом, который вы держите в списке.Чтобы инкапсулировать эту логику, нужно выполнить несколько шагов.Если вы хотите пойти по этому пути, я могу опубликовать для вас код.Я просто не уверен, насколько практично было бы опубликовать код здесь, на StackOverflow, но я могу попытаться сделать его кратким и по существу.В противном случае вам придется выполнять утомительную задачу повторения каждого ожидания метода доступа к индексу для читателя.Процесс инкапсуляции также избавит вас от строк и сделает их более пригодными для повторного использования в ваших тестах.

Кроме того, на данный момент я не уверен, насколько вы хотите сделать существующий код более тестируемым.Поскольку это устаревший код, который не был создан с учетом тестирования.

Другие советы

Я подумал о том, чтобы опубликовать немного кода, но потом вспомнил о курсе JP Boodhoo Nothin But .NET.У него есть пример проекта которым он делится, созданным во время одного из его занятий.Проект размещен на Google-код и это хороший ресурс.Я уверен, что здесь есть несколько полезных советов, которые вы сможете использовать, а также идеи по рефакторингу сопоставления.Весь проект был построен с использованием TDD.

Вы можете поместить экземпляры Foo в список и сравнить объекты с тем, что вы читаете:

var arrFoos = new Foos[]{...}; // what you expect
var expectedFoos = new List<Foo>(arrFoos); // make a list from the hardcoded array of expected Foos
var readerResult = ReadEntireList(reader); // read everything from reader and put in List<Foo>
Expect.ContainSameFoos(expectedFoos, readerResult); // compare the two lists

Кокос,

Там пара вещей не так.Во-первых, такой подход означает, что мне нужно сначала создать Foos, а затем передать их значения программе чтения макетов, которая ничего не делает для уменьшать количество кода, который я пишу.Во-вторых, если значения проходят через считыватель, Foos не будет такой же Foos (ссылочное равенство).Они могут быть равный, но даже это предполагает слишком большую часть класса Foo, которую я не смею трогать на данный момент.

Просто чтобы уточнить: вы хотите иметь возможность проверить, что ваш вызов SQL Server вернул некоторые данные, или что, если у вас есть какие-то данные, вы можете отобразить их обратно в модель?

Если вы хотите проверить свой вызов в SQL, он вернул некоторые данные, мой ответ нашел здесь

@Торан:Я тестирую программное сопоставление данных, возвращаемых из базы данных, с моделью домена в кавычках.Поэтому я хочу издеваться над соединением с базой данных.Что касается другого типа тестов, я бы выбрал комплексное интеграционное тестирование.

@Дол:Полагаю, вы неплохо с этим справились, и я боялся, что это может быть так.Если у вас есть ссылки на какие-либо статьи или тому подобное, где кто-то проделал грязную работу и разложил ее на более легко усваиваемые шаги, я был бы признателен.Примеры кода тоже не помешали бы.У меня есть представление о том, как подойти к этой проблеме, но прежде чем я действительно осмелюсь это сделать, мне нужно будет сделать другие вещи, и если тестирование потребует утомительных издевательств, то я так и сделаю.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top