Skip to content

тестирование в SpringBoot

Для написания теста с использованием аннотации @SpringBootTest в Spring Boot, вам нужно создать тестовый класс, который будет загружать контекст приложения и тестировать функциональность вашего сервиса или репозитория. Вот пример, как это можно сделать для вашего сервиса ArticleService.

Пример теста для ArticleService

  1. Убедитесь, что у вас есть зависимости для тестирования в вашем pom.xml (если вы используете Maven):
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
  1. Создайте тестовый класс для ArticleService:
import static org.mockito.Mockito.*;
import static org.assertj.core.api.Assertions.*;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.Arrays;
import java.util.List;

@SpringBootTest
@ExtendWith(SpringExtension.class)
public class ArticleServiceTest {

    @Autowired
    private ArticleService articleService;

    @MockBean
    private ArticleRepository articleRepository;

    @BeforeEach
    public void setUp() {
        // Здесь можно настроить общие моки, если это необходимо
    }

    @Test
    public void testGetArticlesByCategoryWithPositiveRating() {
        // Подготовка тестовых данных
        Article article1 = new Article("Заголовок 1", "Описание 1", "Природа", 5);
        Article article2 = new Article("Заголовок 2", "Описание 2", "Природа", 3);
        List<Article> articles = Arrays.asList(article1, article2);

        // Настройка поведения мока
        when(articleRepository.findAllByCategoryAndRatingGreaterThanOrderByRatingDesc("Природа", 0))
                .thenReturn(articles);

        // Вызов метода сервиса
        List<Article> result = articleService.getArticlesByCategoryWithPositiveRating("Природа");

        // Проверка результатов
        assertThat(result).isNotNull();
        assertThat(result.size()).isEqualTo(2);
        assertThat(result.get(0).getRating()).isEqualTo(5);
        assertThat(result.get(1).getRating()).isEqualTo(3);

        // Проверка, что метод репозитория был вызван
        verify(articleRepository, times(1)).findAllByCategoryAndRatingGreaterThanOrderByRatingDesc("Природа", 0);
    }
}

Объяснение кода:

  1. Аннотация @SpringBootTest: Эта аннотация указывает, что это тестовый класс для Spring Boot, который будет загружать контекст приложения.

  2. Аннотация @ExtendWith(SpringExtension.class): Эта аннотация позволяет использовать возможности Spring в JUnit 5.

  3. @MockBean: Эта аннотация создает мок для ArticleRepository, который будет использоваться в тестах. Это позволяет изолировать тестируемый сервис от реальной базы данных.

  4. Метод setUp(): Здесь вы можете настроить любые общие данные или моки, которые будут использоваться в тестах.

  5. Тестовый метод testGetArticlesByCategoryWithPositiveRating():

  6. Создает тестовые данные (объекты Article).
  7. Настраивает поведение мока articleRepository, чтобы он возвращал тестовые данные при вызове метода.
  8. Вызывает метод сервиса и проверяет, что результат соответствует ожиданиям.
  9. Проверяет, что метод репозитория был вызван один раз с правильными параметрами.

Этот тест проверяет, что ваш сервис правильно взаимодействует с репозиторием и возвращает ожидаемые результаты.


Да, имя метода в тесте должно соответствовать имени метода в сервисе, который вы хотите протестировать. В вашем случае, если метод в сервисе называется getBestInCategoryGreaterThen, то тест должен вызывать именно этот метод.

Обновленный тест

Вот как должен выглядеть ваш тест с учетом правильного имени метода в сервисе:

package com.example.demo;

import static org.mockito.Mockito.*;
import static org.assertj.core.api.Assertions.*;

import com.example.demo.models.Article;
import com.example.demo.repository.ArticleRepository;
import com.example.demo.services.ArticlesServices;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.Arrays;
import java.util.List;

@SpringBootTest
@ExtendWith(SpringExtension.class)
public class ArticleServiceTest {

    @Autowired
    private ArticlesServices articleService;

    @MockBean
    private ArticleRepository articleRepository;

    @BeforeEach
    public void setUp() {
        // Здесь можно настроить общие моки, если это необходимо
    }

    @Test
    public void testGetBestInCategory() {
        // Подготовка тестовых данных
        Article article1 = new Article("Заголовок 1", "Описание 1", "Природа", 5);
        Article article2 = new Article("Заголовок 2", "Описание 2", "Природа", 3);
        List<Article> articles = Arrays.asList(article1, article2);

        // Настройка поведения мока
        when(articleRepository.findAllByCategoryOrderByRatingDesc("Природа"))
                .thenReturn(articles);

        // Вызов метода сервиса
        List<Article> result = articleService.getBestInCategory("Природа");

        // Проверка результатов
        assertThat(result).isNotNull();
        assertThat(result.size()).isEqualTo(2);
        assertThat(result.get(0).getRating()).isEqualTo(5);
        assertThat(result.get(1).getRating()).isEqualTo(3);

        // Проверка, что метод репозитория был вызван
        verify(articleRepository, times(1)).findAllByCategoryOrderByRatingDesc("Природа");
    }

    @Test
    public void testGetBestInCategoryGreaterThen() {
        // Подготовка тестовых данных
        Article article1 = new Article("Заголовок 1", "Описание 1", "Природа", 5);
        Article article2 = new Article("Заголовок 2", "Описание 2", "Природа", 3);
        Article article3 = new Article("Заголовок 3", "Описание 3", "Природа", 0);
        Article article4 = new Article("Заголовок 4", "Описание 4", "Природа", 2);

        List<Article> articles = Arrays.asList(article1, article2, article3, article4);

        // Настройка поведения мока
        when(articleRepository.findAllByCategoryAndRatingGreaterThanOrderByRatingDesc("Природа", 0))
                .thenReturn(Arrays.asList(article1, article2, article4)); // Возвращаем только статьи с рейтингом > 0
//        Вы правы в том, что метод findAllByCategoryAndRatingGreaterThanOrderByRatingDesc в вашем репозитории должен возвращать только те статьи, у которых рейтинг больше указанного значения. Однако, когда вы используете моки, вы фактически имитируете поведение этого метода, и именно поэтому вы можете настроить, что он будет возвращать.

       // Вызов метода сервиса
        List<Article> result = articleService.getBestInCategoryGreaterThen("Природа", 0);

        // Проверка результатов
        assertThat(result).isNotNull();
        assertThat(result.size()).isEqualTo(3); // Ожидаем 3 статьи с рейтингом > 0
        assertThat(result).containsExactlyInAnyOrder(article1, article2, article4); // Проверяем, что возвращаются именно эти статьи

        // Проверка, что метод репозитория был вызван
        verify(articleRepository, times(1)).findAllByCategoryAndRatingGreaterThanOrderByRatingDesc("Природа", 0);
    }

}

Изоляция теста: Вы не тестируете реальную базу данных, а только логику вашего сервиса. Поэтому вы можете настроить мок так, как вам нужно, чтобы проверить, как ваш сервис обрабатывает данные.

Проверка логики фильтрации: Ваша цель — проверить, правильно ли ваш метод getBestInCategoryGreaterThen фильтрует статьи. Если вы хотите протестировать, что он возвращает только статьи с рейтингом больше 0, вы можете настроить мок так, чтобы он возвращал только те статьи, которые соответствуют этому критерию.

результат теста

> Task :test
BUILD SUCCESSFUL in 5s
4 actionable tasks: 2 executed, 2 up-to-date
6:31:13 PM: Execution finished ':test --tests "com.example.demo.ArticleServiceTest"'.

пример

https://gitlab.com/synergy9980417/razdel2/8_11/-/tree/main/src/test/java/com/example/demo?ref_type=heads