Как мне проверить метод, который заполняет список из DataReader? - PullRequest
5 голосов
/ 27 августа 2008

Итак, я работаю над устаревшим кодом, который сильно влияет на ручные операции с базой данных. Я пытаюсь сохранить некоторое подобие качества здесь, поэтому я стараюсь как можно больше использовать 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, потому что их EULA было слишком страшным для моих вкусов в последний раз, когда я проверял.

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

Ответы [ 6 ]

1 голос
/ 27 августа 2008

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

1 голос
/ 27 августа 2008

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

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

0 голосов
/ 27 августа 2008

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

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

0 голосов
/ 27 августа 2008

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

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

0 голосов
/ 27 августа 2008

Кокос

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

0 голосов
/ 27 августа 2008

Вы можете поместить экземпляры 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
...