В этой статье показано, как использовать аннотацию 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/”