Модульное тестирование приложения Spring Boot Сервисный уровень - PullRequest
2 голосов
/ 14 октября 2019

Я немного озадачен возможностями тестирования и утилитами, предоставляемыми Spring Boot.

Я использую spring-boot-starter-test в своем проекте, и я хотел бы провести модульное тестирование своих служб без подключения к базе данных.

В настоящее время я использую @WebMvcTest для тестовых наборов контроллеров и @SpringBootTest для всех остальных тестовых классов.

Но я где-то читал, что @SpringBootTest предназначен для использованиятолько в интеграционных тестах ...

Чтение документации Я не понял, что такое предлагаемый подход для сервисов. Стоит ли тестировать их только в интеграции с репозиториями?

ОБНОВЛЕНИЕ

Это отрывок из тестового класса для одного из моих сервисов:

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@SpringBootTest
internal class SignupServiceTest(
        @Autowired val signupService: SignupService
) {
    @MockkBean
    lateinit var userRepository: UserRepository

    @Test
    fun `should return exception if username already used`() {
        every { userRepository.findByUsername("registered-user") } returns fakeUser(username = "registered-user")

        assertThatThrownBy {
            signupService.createNewAccount(fakeSignupForm(username = "registered-user"))
        }.isExactlyInstanceOf(UsernameNotAvailableException::class.java)
    }

    // ... other tests

}

Ответы [ 3 ]

2 голосов
/ 14 октября 2019

Вы должны отдавать предпочтение внедрению модульных тестов для тестирования своей бизнес-логики (тесты, выполняемые без Spring, простые тесты JUnit), а не интеграционным тестам (тесты, запускающие контейнер Spring, @SpringBootTest), поскольку они более легкие и дают обратную связь намного быстрее.

Цитата из Spring Boot doc

Одним из основных преимуществ внедрения зависимостей является то, что он должен упростить ваш код для модульного тестирования. Вы можете создавать экземпляры объектов с помощью оператора new, даже не задействуя Spring. Вы также можете использовать фиктивные объекты вместо реальных зависимостей.

Часто вам нужно выйти за рамки модульного тестирования и начать интеграционное тестирование (с помощью Spring ApplicationContext). Полезно иметь возможность выполнять интеграционное тестирование, не требуя развертывания приложения или подключения к другой инфраструктуре.

2 голосов
/ 14 октября 2019

Использование @SpringBootTest для модульных тестов немного излишне. Потому что это загрузит весь контекст приложения.

Для тестирования отдельных (сервисных) классов я бы использовал @RunWith(MockitoJUnitRunner.class), а вместо @Autowired и @MockBean используйте @Mock и @InjectMocks (Если вы используете инжекцию в конструктор, вам не нужноиспользовать это., который был бы лучшим вариантом)

Вы все еще можете использовать @Autowired с @ContextConfiguration и загружать определенные классы (если не слишком много переходных зависимостей)

Если выесли вы не хотите использовать макеты, тогда вы можете использовать встроенные базы данных и использовать @DataMongoTest или @DataJpaTest и использовать возможности тестирования Springboot.

Не усложняйте ....

0 голосов
/ 14 октября 2019

попробуйте смоделировать вызовы к базе данных, используя mockito, или используйте базу данных h2 для тестов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...