Начиная с этой концепции:
1) Начните с поведения, которое вы желаете. Напишите тест для этого. Смотри тест провалился.
2) Напишите достаточно кода, чтобы пройти тест. Смотреть все тесты проходят.
3) Ищите избыточный / неаккуратный код -> рефакторинг. Смотрите тесты еще пройти. Перейти к 1
Итак, в # 1, скажем, вы хотите создать новую команду (я перехожу к тому, как команда будет работать, так что терпите меня). (Кроме того, я буду немного прагматичным, а не экстремальным TDD)
Новая команда называется MakeMyLunch, поэтому вы сначала создаете тест для ее создания и получаете имя команды:
@Test
public void instantiateMakeMyLunch() {
ICommand command = new MakeMyLunchCommand();
assertEquals("makeMyLunch",command.getCommandName());
}
Это терпит неудачу, вынуждая вас создать новый класс команд и заставить его вернуть его имя (пурист сказал бы, что это два раунда TDD, а не 1). Таким образом, вы создаете класс и реализуете его интерфейс ICommand, включая возвращение имени команды. Запуск всех тестов теперь показывает все прохождения, поэтому вы продолжаете искать возможности рефакторинга. Наверное, нет.
Итак, затем вы хотите, чтобы он реализовал execute. Поэтому вы должны спросить: откуда мне знать, что «MakeMyLunch» успешно «сделал мой обед». Какие изменения в системе из-за этой операции? Могу ли я проверить это?
Предположим, что это легко проверить на:
@Test
public void checkThatMakeMyLunchIsSuccessful() {
ICommand command = new MakeMyLunchCommand();
command.execute();
assertTrue( Lunch.isReady() );
}
В других случаях это сложнее, и вы действительно хотите проверить обязанности испытуемого (MakeMyLunchCommand). Возможно, ответственность MakeMyLunchCommand заключается во взаимодействии с холодильником и микроволновой печью. Таким образом, чтобы проверить это, вы можете использовать макет Холодильник и макет Микроволновая печь. [два примера макетов фреймворка - Mockito и nMock или посмотрите здесь .]
В этом случае вы должны сделать что-то вроде следующего псевдокода:
@Test
public void checkThatMakeMyLunchIsSuccessful() {
Fridge mockFridge = mock(Fridge);
Microwave mockMicrowave = mock(Microwave);
ICommand command = new MakeMyLunchCommand( mockFridge, mockMicrowave );
command.execute();
mockFramework.assertCalled( mockFridge.removeFood );
mockFramework.assertCalled( microwave.turnon );
}
Пурист говорит: проверь ответственность своего класса - его взаимодействия с другими классами (открыла ли команда холодильник и включила ли микроволновая печь?).
Прагматик говорит, что тест для группы классов и тест на результат (ваш обед готов?).
Найдите правильный баланс, который работает для вашей системы.
(Примечание: учтите, что, возможно, вы пришли к своей структуре интерфейса слишком рано. Возможно, вы сможете позволить этому развиваться по мере написания своих модульных тестов и реализаций, и на шаге 3 вы «заметите» общую возможность интерфейса).