В статье представлены перспектива и некоторые примеры кода о том, как можно сделать кое-что интересное с помощью разработки через тестирование (TDD) и Mocking. Примеры кода сделаны на Java.
Кратко разберемся, что такое TDD и издевательство?
Что такое TDD?
Проще говоря, разработка через тестирование — это процесс разработки программного обеспечения, в котором разработчики сначала пишут тесты, а затем пишут достаточно кода, чтобы пройти эти тесты. После того, как все тесты пройдены, они проводят рефакторинг кода для повышения качества кода. Ниже приведены ключевые преимущества использования TDD в качестве процесса разработки:
- Заставляет разработчиков тщательно продумывать различные тесты, которые можно использовать для проверки функциональных / бизнес-требований. Таким образом, он устраняет множество ошибок, которые могут быть обнаружены на этапах QA и постпроизводства, которые очень трудно исправить.
- Разработчики очень тесно сотрудничают как с бизнес-аналитиками, так и с инженерами-тестировщиками. Это пропагандирует командную работу .
- Рефакторинг кода можно сделать простым способом.
Следующая диаграмма представляет процесс TDD:
Вот несколько хороших страниц в Интернете, чтобы начать работу с TDD:
Что такое издевательство?
Mocking — это явление модульного тестирования, которое помогает тестировать объекты изолированно, заменяя зависимые объекты сложным поведением тестовыми объектами с предопределенным / смоделированным поведением. Эти тестовые объекты называются фиктивными объектами.
Как TDD сияет с Mocking?
В TDD основная цель — пройти тесты, которые написаны первыми. Однако в реальном сценарии, когда человек начинает писать код, он сталкивается с различными случаями, которые могут быть сделаны как зависимые классы. Ниже приведены различные варианты, которые можно сделать:
- Без насмешек : напишите весь код в одном классе и пройдите тесты. Как только тесты пройдут, проведите рефакторинг кода, извлекая методы и классы. Убедитесь, что тесты пройдены.
- С Mocking : вместо необходимости писать весь код одновременно в одном и том же классе, просто реализуйте поток, используя зависимые классы, и убедитесь, что тесты пройдены. При этом просто определите зависимые классы и смоделируйте их в модульных тестах. Делая это, можно было бы обеспечить прохождение потока метода без необходимости писать весь код. Преимущество использования насмешек заключается в интересных моделях поведения, которые можно моделировать без необходимости в коде. Это продемонстрировано позже в этой статье с примерами кода. Следующая диаграмма демонстрирует тот факт, что при моделировании может не потребоваться написать зависимые классы и все же завершить поток кода, в то же время убедившись, что все связанные тесты пройдены.
Требование к программному обеспечению
Мы попробуем и посмотрим, как TDD сияет с насмешками с этим требованием. Требуется добавить новый ресторан в систему базы данных ресторанов. Нужно иметь возможность добавить ресторан, если введены обязательные данные.
Модульный тест, написанный первым
Глядя на требования, можно придумать несколько следующих тестов:
- restaurantNotCreatedDueToValidationFailure
- restaurantNotCreatedDueToPersistenceFailure
- restaurantCreated
Вот как выглядит модульный тест (написанный первым):
Модульный тест: NewRestaurantTest.java
public class NewRestaurantTest { @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void restaurantCreated() { } @Test public void restaurantNotCreatedDueToValidationFailure() { } @Test public void restaurantNotCreatedDueToPersistenceFailure() { } }
Класс Дизайн
Глядя на вышеприведенные тесты, можно увидеть следующие классы:
- NewRestaurant: Включая логику для создания ресторана
- Ресторан: Доменный объект, представляющий ресторан
- RestaurantValidation: состоит из логики проверки, соответствующей бизнес-правилам, необходимым для добавления нового ресторана
- RestaurantDAO: состоит из логики для сохранения объекта ресторана в базе данных
Класс Java: NewRestaurant.java
Обратите внимание на метод createRestaurant, в котором проверенные и постоянные методы вызываются для классов RestaurantValidation и RestaurantDAO соответственно. Эти методы, однако, являются пустыми методами в соответствующих классах. Однако с этими методами процесс создания ресторана завершен. Посмотрите на код ниже.
public Restaurant createRestaurant( Restaurant restaurant ) { Restaurant retRest = null; if( resVal.validated( restaurant ) ) { if( resDAO.persist( restaurant ) ) { retRest = new Restaurant( restaurant ); } } return retRest; }
Чтобы проверить приведенный выше код, следующий код демонстрирует использование макетов. Обратите внимание, как проверенные и сохраняемые методы для RestaurantValidation и RestaurantDAO соответственно подвергаются насмешкам в трех различных тестах, показанных ниже.
Модульный тест: NewRestaurantTest.java
@Test public void restaurantCreated() { Restaurant restaurant = new Restaurant(); Mockito.when( restVal.validated(restaurant)).thenReturn( true ); Mockito.when( restDAO.persist(restaurant)).thenReturn( true ); Restaurant newRest = newRestaurant.createRestaurant(restaurant); Mockito.verify( restVal ).validated(restaurant); Mockito.verify( restDAO ).persist(restaurant); assertNotNull( newRest ); } @Test public void restaurantNotCreatedDueToValidationFailure() { Restaurant restaurant = new Restaurant(); Mockito.when( restVal.validated(restaurant)).thenReturn( false ); Mockito.when( restDAO.persist(restaurant)).thenReturn( true ); Restaurant newRest = newRestaurant.createRestaurant(restaurant); Mockito.verify( restVal ).validated(restaurant); Mockito.verify( restDAO, Mockito.never() ).persist(restaurant); assertNull( newRest ); } @Test public void restaurantNotCreatedDueToPersistenceFailure() { Restaurant restaurant = new Restaurant(); Mockito.when( restVal.validated(restaurant)).thenReturn( true ); Mockito.when( restDAO.persist(restaurant)).thenReturn( false ); Restaurant newRest = newRestaurant.createRestaurant(restaurant); Mockito.verify( restVal ).validated(restaurant); Mockito.verify( restDAO ).persist(restaurant); assertNull( newRest ); }
Таким образом, в качестве резюме, если вы хотите получить больше удовольствия от TDD, используйте насмешки, поскольку они позволяют моделировать некоторые интересные варианты поведения без необходимости написания какого-либо кода.