JavaRush/Курсы/JSP & Servlets/Настройка окружения теста в JUnit

Настройка окружения теста в JUnit

Открыта

3.1 Аннотации @BeforeEach, @AfterEach

Обрати внимание, что в предыдущем примере нам в каждом методе приходилось писать код для создания объекта Calculator.

Конечно, это всего одна строчка, но если мы будем тестировать реальные системы, то часто будет возникать ситуация, когда нужно создать и сконфигурировать несколько объектов, что может занять несколько десятков строк кода. Пример:

//Создаем объект HttpClient
 HttpClient client = HttpClient.newBuilder()
  	.version(Version.HTTP_1_1)
  	.followRedirects(Redirect.NORMAL)
      .connectTimeout(Duration.ofSeconds(20))
  	.proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
      .authenticator(Authenticator.getDefault())
  	.build();

 //Создаем объект HttpRequest
HttpRequest request = HttpRequest.newBuilder()
   .uri(new URI("https://javarush.com"))
   .headers("Content-Type", " application/octet-stream")
   .POST( HttpRequest.BodyPublishers. ofInputStream ( () -> is; ))
   .build();

 //Вызываем метод send()
 HttpResponse






  response = client.send(request, BodyHandlers.ofString()); System.out.println(response.statusCode()); System.out.println(response.body());

В примере выше мы создали и сконфигурировали объект HttpClient и хотим протестировать работу метода send().

Чтобы каждый раз в тестовом методе не писать создание объекта HttpClient, его можно вынести в отдельный метод и поставить ему специальную аннотацию @BeforeEach. Тогда Junit будет вызывать этот метод перед каждым тестовым методом. Пример:

class HttpClientTest {
 	public HttpClient client;

   	@BeforeEach
	public void init(){
   	   client = HttpClient.newBuilder()
   	        .version(Version.HTTP_1_1)
   	        .followRedirects(Redirect.NORMAL)
   	        .connectTimeout(Duration.ofSeconds(20))
   	        .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
   	        .authenticator(Authenticator.getDefault())
   	        .build();
	}

   	@Test
	public void send200() throws Exception {
 	   //Создаем объект HttpRequst()
     	HttpRequest request = HttpRequest.newBuilder(new URI("https://javarush.com")).build();

 	   //Вызываем метод send()
 	   HttpResponse






response = client.send(request, BodyHandlers.ofString()); assertEquals(200, response.statusCode()); } @Test public void send404() throws Exception { //Создаем объект HttpRequst() HttpRequest request = HttpRequest.newBuilder(new URI("https://javarush.com/unknown")).build(); //Вызываем метод send() HttpResponse

 response = client.send(request, BodyHandlers.ofString()); assertEquals(404, response.statusCode()); } }

Также можно создать специальный метод, который будет вызываться каждый раз после очередного тестового метода, и подчищать использованные ресурсы, писать что-то в лог и т. п. Такой метод нужно пометить аннотацией @AfterEach.

Если у тебя есть 3 тестовых метода test1(), test2() и test3(), то порядок вызова будет таким:

  • BeforeEach-метод
  • test1()
  • AfterEach-метод
  • BeforeEach-метод
  • test2()
  • AfterEach-метод
  • BeforeEach-метод
  • test3()
  • AfterEach-метод

3.2 Аннотации @BeforeAll, @AfterAll

JUnit также позволяет добавить метод, который будет вызван один раз перед всеми тестовыми методами. Такой метод нужно пометить аннотацией @BeforeAll. Для нее так же существует парная аннотация @AfterAll. Метод, помеченный ею, JUnit вызовет после всех тестовых методов.

Давай напишем специальный пример, который позволяет лучше понять, как это все работает. За основу возьмем тестирование нашего калькулятора:

class CalculatorTest {
    private Calculator calc = new Calculator();

    @BeforeAll
    public static void init(){
        System.out.println("BeforeAll init() method called");
    }

    @BeforeEach
    public void initEach(){
        System.out.println("BeforeEach initEach() method called");
    }

    @Test
    public void add(){
        System.out.println("Testing Addition");
    }

    @Test
    public void sub() {
        System.out.println("Testing Subtraction");
    }

    @Test
    public void mul(){
        System.out.println("Testing Multiplication");
    }

    @Test
    public void div() {
        System.out.println("Testing Division");
    }
}

Этот тест напечатает в консоль такой текст:


BeforeAll init() method called
BeforeEach initEach() method called
Testing Addition
 
BeforeEach initEach() method called
Testing Subtraction
 
BeforeEach initEach() method called
Testing Multiplication
 
BeforeEach initEach() method called
Testing Division
Комментарии (7)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Denis Odesskiy Full Stack Developer
18 августа 2025, 13:02
Чтобы работал тест с калькулятором и @BeforeEach, например, создайте приватное поле типа Calculator, затем проинициализируйте его в методе помеченной аннотацией @BeforeEach, и уберите создание экземпляров класса из @Test, теперь они там лишние. А то, как показано в этой лекции непонятно, что вызвать в @BeforeEach, чтобы тесты калькулятора работали.
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class CalculatorTest {
    private Calculator calc;
    @BeforeEach
    public void initEach() {
        calc = new Calculator();
    }

    @Test
    public void add() {
        int result = calc.add(2, 3);
        assertEquals(5, result);
    }

    @Test
    public void sub() {
        int result = calc.sub(10, 10);
        assertEquals(0, result);
    }

    @Test
    public void mul() {
        int result = calc.mul(-5, -3);
        assertEquals(15, result);
    }

    @Test
    public void div() {
        int result = calc.div(2, 3);
        assertEquals(0, result);
    }
}
Рустам
Уровень 115
8 марта 2025, 06:28
Оформление кода - пушка
Андрей
Уровень 2
Expert
18 июля 2024, 13:05
Если кто-то захочет запустить HttpClientTest и у него проблема с Authenticator.getDefault() - NPE то иницилизируйте по другому:
@BeforeEach
   public void init(){
           client = HttpClient.newHttpClient();
   }
или закоментируйте эти строки
public void init(){
        client = HttpClient.newBuilder()
                .version(HttpClient.Version.HTTP_1_1)
                .followRedirects(HttpClient.Redirect.NORMAL)
                .connectTimeout(Duration.ofSeconds(20))
//                .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
//                .authenticator(Authenticator.getDefault())
                .build();
    }
или настройте реальный прокси....
Павел
Уровень 19
Expert
14 декабря 2023, 09:44
Хорошо было бы сначала познакомиться заранее где-нибудь в лекциях с HttpClient, HttpRequest, а потом использовать эти классы в примерах.
eldar516Работает в Аэропорт Шереметьево
19 июня 2022, 22:04
на 4 и 5 junit методы аннотированные BeforeAll и AfterAll выбрасывают JUnitException, если не аннотировать класс @TestInstance(TestInstance.Lifecycle.PER_CLASS)
Ramz
Уровень 35
8 июля 2022, 15:37
Либо static
Zhenya Workout
Уровень 43
26 августа 2023, 16:11
Методы помеченные данными аннотациями должны быть статичными.