В этой статье показано, как использовать аннотацию JUnit 5 @Nested
для группировки тестов вместе.
P.S Протестировано с JUnit 5.5.2
Почему вложенные тесты? Создавать вложенные тесты необязательно. Тем не менее, это помогает создавать иерархические контексты для структурирования связанных модульных тестов вместе; короче говоря, это помогает поддерживать тесты чистыми и удобочитаемыми.
Давайте рассмотрим следующий пример – Тесты для Обслуживание клиентов
.
1. Единый Тестовый класс
1.1 По умолчанию мы можем создавать все тесты в одном классе, как это:
package com.mkyong.nested.samples; import com.mkyong.customer.service.CustomerService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @DisplayName("Test Customer Service") public class CustomerServiceMethodTest { CustomerService customerService; @BeforeEach void createNewObjectForAll() { System.out.println("New CustomerService()"); //customerService = new CustomerServiceJDBC(); } @Test void findOne_with_id() { //customerService.findOneById(2L); } @Test void findOne_with_name() { //customerService.findOneByName(2L); } @Test void findOne_with_name_regex() { //customerService.findOneByNameRegex("%s"); } @Test void findAll_with_ids() { //customerService.findAllByIds(Arrays.asList(2, 3, 4)); } @Test void findAll_with_name_like() { //customerService.findAllByName("mkyong"); } @Test void update_with_new() { //customerService.update(new Customer()); } @Test void update_with_existing() { //customerService.update(new Customer()); } }
Вывод в среде IDE.
Если Служба поддержки клиентов
добавляет дополнительные функции, этот единственный тестовый класс будет легко перегружен сотнями методов тестирования. В конце концов, мы создаем беспорядочный, значительный и неорганизованный единый тестовый класс.
2. Тесты по классам
2.1 Некоторые разработчики начали группировать связанные яички по имени класса следующим образом:
package com.mkyong.nested.samples; import com.mkyong.customer.service.CustomerService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class CustomerServiceFindOneTest { CustomerService customerService; @BeforeEach void createNewObjectForAll() { System.out.println("New CustomerService()"); //customerService = new CustomerServiceJDBC(); } @Test void findOne_with_id() { //customerService.findOneById(2L); } @Test void findOne_with_name() { //customerService.findOneByName(2L); } @Test void findOne_with_name_regex() { //customerService.findOneByNameRegex("%s"); } }
package com.mkyong.nested.samples; import com.mkyong.customer.service.CustomerService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class CustomerServiceFindAllTest { CustomerService customerService; @BeforeEach void createNewObjectForAll() { System.out.println("New CustomerService()"); //customerService = new CustomerServiceJDBC(); } @Test void findAll_with_ids() { //customerService.findAllByIds(Arrays.asList(2, 3, 4)); } @Test void findAll_with_name_likeY() { //customerService.findAllByName("mkyong"); } }
package com.mkyong.nested.samples; import com.mkyong.customer.service.CustomerService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class CustomerServiceUpdateTest { CustomerService customerService; @BeforeEach void createNewObjectForAll() { System.out.println("New CustomerService()"); //customerService = new CustomerServiceJDBC(); } @Test void update_with_new() { //customerService.update(new Customer()); } @Test void update_with_existing() { //customerService.update(new Customer()); } }
Если Служба поддержки клиентов
добавляет дополнительные функции, например, новые 30+ методов, собираемся ли мы создать 30+ тестовых классов для Службы поддержки клиентов
? Как запустить более 30 тестовых классов по шаблону или создать новый набор тестов?
3. Вложенные Тесты
3.1 Для большого класса мы должны рассмотреть @Вложенные
тесты, все тесты в одном тестовом классе (в иерархической структуре), а иерархический вывод в IDE делает тесты более удобочитаемыми.
Кроме того, мы также можем инициализировать объект и повторно использовать его для всех вложенных тестов.
package com.mkyong.nested; import com.mkyong.customer.service.CustomerService; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @DisplayName("Test Customer Service") public class CustomerServiceNestedTest { CustomerService customerService; // Create one customerService object and reuse for all the nested tests @Test @DisplayName("new CustomerService() for all the nested methods.") void createNewObjectForAll() { System.out.println("New CustomerService()"); //customerService = new CustomerServiceJDBC(); } @Nested @DisplayName("findOne methods") class FindOne { @Test void findOne_with_id() { //customerService.findOneById(2L); } @Test void findWith_with_name() { //customerService.findOneByName(2L); } @Test void findWith_with_name_regex() { //customerService.findOneByNameRegex("%s"); } } @Nested @DisplayName("findAll methods") class FindAll { @Test void findAll_with_ids() { //customerService.findAllByIds(Arrays.asList(2, 3, 4)); } @Test void findAll_with_name_likeY() { //customerService.findAllByName("mkyong"); } } @Nested @DisplayName("update methods") class Update { @Test void update_with_new() { //customerService.update(new Customer()); } @Test void update_with_existing() { //customerService.update(new Customer()); } } }
Вывод в среде IDE.
Скачать Исходный Код
Рекомендации
Оригинал: “https://mkyong.com/junit5/junit-5-nested-test-examples/”