тестирование в SpringBoot
Для написания теста с использованием аннотации @SpringBootTest
в Spring Boot, вам нужно создать тестовый класс, который будет загружать контекст приложения и тестировать функциональность вашего сервиса или репозитория. Вот пример, как это можно сделать для вашего сервиса ArticleService
.
Пример теста для ArticleService
- Убедитесь, что у вас есть зависимости для тестирования в вашем
pom.xml
(если вы используете Maven):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
- Создайте тестовый класс для
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);
}
}
Объяснение кода:
-
Аннотация
@SpringBootTest
: Эта аннотация указывает, что это тестовый класс для Spring Boot, который будет загружать контекст приложения. -
Аннотация
@ExtendWith(SpringExtension.class)
: Эта аннотация позволяет использовать возможности Spring в JUnit 5. -
@MockBean
: Эта аннотация создает мок дляArticleRepository
, который будет использоваться в тестах. Это позволяет изолировать тестируемый сервис от реальной базы данных. -
Метод
setUp()
: Здесь вы можете настроить любые общие данные или моки, которые будут использоваться в тестах. -
Тестовый метод
testGetArticlesByCategoryWithPositiveRating()
: - Создает тестовые данные (объекты
Article
). - Настраивает поведение мока
articleRepository
, чтобы он возвращал тестовые данные при вызове метода. - Вызывает метод сервиса и проверяет, что результат соответствует ожиданиям.
- Проверяет, что метод репозитория был вызван один раз с правильными параметрами.
Этот тест проверяет, что ваш сервис правильно взаимодействует с репозиторием и возвращает ожидаемые результаты.
Да, имя метода в тесте должно соответствовать имени метода в сервисе, который вы хотите протестировать. В вашем случае, если метод в сервисе называется 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