2010-08-19 6 views
1

Прежде всего позвольте мне сказать, что я работаю из устаревшего кода. Поэтому некоторые изменения могут быть сделаны, но не радикальными.Rhino Mocking и TDD с устаревшим кодом

Моя проблема: у меня есть объект «Vehicle», он довольно прост, но на нем нет никаких интерфейсов или чего-либо еще. Этот проект был создан до того, как TDD действительно начала становиться более основным потоком. В любом случае, мне нужно добавить новый метод для изменения стартового пробега автомобиля. Я думал, что это будет хорошее начало, чтобы попробовать TDD и Mocking, поскольку я новичок. Моя проблема в том, что мне нужно создать транспортное средство, чтобы выполнить некоторые проверки, связанные с переходом в базу данных. Извините, если мой вопрос не на 100% ясен, почему я отправляю сообщения, так как я немного смущен, когда Rhino Mocks вписывается (и если мне это нужно!).

ответ

0

Легко ли создать экземпляр типа транспортного средства (объект), а затем вызвать свой метод для проверки? Если да, то, скорее всего, вам не нужен макет.

Однако, если у вашего типа транспортного средства есть зависимости (например, объект доступа к базе данных), что ему необходимо выполнить действие, которое вы хотите протестировать, то вы хотели бы использовать объект доступа к макетной базе данных, который возвращает законченные значения для теста, поскольку вы хотите, чтобы ваши тесты устройств работали быстро.

Vehicle [depends On>] OwnerRepository [satisfied By] SQLOwnerRepository 

Таким образом, вы приведете интерфейс (OwnerRepository, чтобы получить подробную информацию о владельце, скажем), чтобы отделить DB взаимодействия (определить контракт) между ними. Сделайте свою реальную зависимость (здесь SQLOwnerRepository) реализуйте этот интерфейс. Также создайте свой код таким образом, чтобы зависимости могли быть введены, например.

public Vehicle (OwnerRepository ownerRepository) 
{ _ownerRepository = ownerRepository; // cache in member variable } 

В настоящее время в тестовом коде,

Vehicle [depends On >] OwnerRepository [satisifed By] MockOwnerRepository 

У вас есть рамки, которые данные интерфейс будет создавать макет реализации этого (см рамки Rhino/MOq). Таким образом, вам больше не требуется фактическое соединение с БД для проверки вашего класса Vehicle. Mocks используются для абстрагирования отнимающих много времени/неконтролируемых зависимостей, чтобы ваши тесты устройств были быстрыми/предсказуемыми.

Я бы рекомендовал прочитать «Инъекция зависимостей», чтобы лучше понять, когда и почему использовать издевательства.

+0

Я отправил ответ с полезной ссылкой. – Lijo

2

Проблема заключается в зависимостях. Ваш класс автомобиля зависит от базы данных. Надеемся, что все взаимодействия с базой данных были инкапсулированы в класс хороший, мы вернемся к этому через секунду. Когда вы запускаете свой модульный тест, вы хотите испытать класс автомобиля, не заботясь о базе данных. Например, вы хотите проверить, что ваш метод SpeedUp (int x) действительно увеличивает общую скорость на x. В этом методе первое, что он делает, это запрос БД для его текущей скорости. Это означает, что вы должны иметь БД для тестирования! Плотина, это звучит не очень быстро и не повторяется. Также много настроек для запуска теста.

Не было бы здорово, если бы у нас была бы притворная БД? Это то, где насмехается. Мы создаем Mock класса, у которого есть все взаимодействие с БД, инкапсулированное. Затем мы настраиваем макет для ответа с предварительно запрограммированным значением. Так, например, когда мы запрашиваем DB для текущей скорости, вы возвращаете 100.

Итак, теперь, когда мы тестируем макет, возвращается 100, и мы можем утверждать, что SpeedUp (int x) принимает 100 и добавляет x к нему.

1

Rhino mocks может создавать только mocks из интерфейсов или абстрактных классов, в которых не существует вашего устаревшего кода.

TypeMock может издеваться над чем угодно, но не является бесплатным.

Вы можете использовать Microsoft Moles, чтобы издеваться над ними.

Следует, однако, учитывать, что Мольс должен быть вашим последним решением, лучше реорганизовать ваш код и сделать его проверяемым путем абстрагирования вашего datalayer с вашего бизнес-уровня.

HTH

0

Неповторный ответ на ваш вопрос. Однако стоит взглянуть на следующее.

Gabriel Schenker опубликовал информацию о применении TDD в унаследованных системах. PTOM – Brownfield development – Making your dependencies explicit

В этой статье объясняется создание dependencies explicit и использование инъекции зависимостей. Также сообщается о Poor Man’s Dependency Injection. Это необходимо, если существует только конструктор по умолчанию.

Что-то вроде

public OrderService() : this(
    new OrderRepository(), 
    new EmailSender(ConfigurationManager.AppSettings["SMTPServer"]) 
    ) 

В статье также занимается созданием обертки для ConfigurationManager за то, что проверяемыми.

Смежные вопросы