Как запустить модульный тест с использованием SpringBoot 2 - PullRequest
1 голос
/ 15 апреля 2020

У меня есть следующий тест:

@SpringBootTest
@ExtendWith(SpringExtension.class)
class BookServiceImplTest {
    @MockBean
    private BookRepository bookRepository;
    @MockBean
    private LibraryService libraryService;

    @Autowired
    private BookServiceImpl bookService;

    @Test
    void create() {
        BookRequestDTO bookRequestDTO = new BookRequestDTO();
        Library library = new Library();
        Book expectedBook = new Book();
        when(libraryService.getById(bookRequestDTO.getLibraryId()))
                .thenReturn(library);
        when(bookRepository.save(any(Book.class)))
                .thenReturn(expectedBook);

        Book actualBook = bookService.create(bookRequestDTO);

        assertEquals(expectedBook, actualBook);
    }
}

Это нормально, и он работает, но мне было интересно, есть ли способ запустить его как модульный тест вместо интеграционных тестов и по-прежнему использовать @ MockBean @Autowired. Или я что-то упустил?

Я пытался оставить только @ExtendWith (SpringExtension.class), но я получил исключение о том, что компонент BookServiceImpl не найден.

Я знаю, как это сделать с помощью MockitoExtension и @Mock, @InjectMocks, но мне было интересно, есть ли более SpringBoot способ сделать это?

Ответы [ 2 ]

1 голос
/ 16 апреля 2020

Вы можете сделать это модульным тестом в четыре этапа:

  • Удалить аннотацию @SpringBootTest, так как она раскручивает весь контекст Spring - бесполезно для юнит-тестов, где все соучастники высмеиваются
  • Удалите @Autowired аннотацию из BookServiceImpl объявления и добавьте @BeforeEach метод установки, в котором вы инициализируете bookService, передавая bookRepository и libraryService в качестве параметров
  • Использовать MockitoExtension вместо SpringExtension в аннотации ExtendWith. Здесь я предполагаю, что вы можете использовать библиотеку типа Mockito для насмешек ваших соавторов
  • Использовать @Mock Mockito вместо @MockBean, так как мы вручную инициализируем bookService, поэтому нет необходимости иметь дело с Spring bean

Чтобы добавить немного к вашему первому вопросу: @Mockbean и @Autowired - аннотации, которые имеют смысл для интеграционных тестов, поскольку они обрабатывают издевательство и инъекция бобов. Модульные тесты должны рассматривать этот класс изолированно, имитируя взаимодействие с другими классами, поэтому нет необходимости раскручивать контекст приложения и настраивать bean-компоненты.

0 голосов
/ 16 апреля 2020
  1. Удалите @SpringBootTest, это загрузит весь контекст и замедлит ваши тесты. Роль @MockBean состоит в том, чтобы создать макет из указанного компонента и добавить его в контекст. Поскольку контекст не запущен, нет смысла использовать @MockBean

  2. Аннотировать ваш класс модульного теста с помощью @RunWith(SpringRunner.class)

  3. Для введения зависимостей Это хорошая практика для явного создания файла конфигурации и явного макета bean-компонентов и создания целевого bean-компонента с их использованием. Предполагая, что вы используете инжекцию на основе конструктора:

    @Profile("test")
    @Configuration
    public class BookServiceTestConfiguration {
    
    
        @Bean
        public BookRepository bookRepository() {
            return Mockito.mock(BookRepository.class);
        }
    
        @Bean
        public LibraryService libraryService() {
            return Mockito.mock(LibraryService.class);
        }
    
        @Bean
        public BookService bookService() {
           BookServiceImpl bookService = new BookServiceImpl(
                    bookRepository(), libraryService()
            );
    
           return userGroupService;
        }
    }
    

Затем напишите свой тестовый класс как:

    @ActiveProfiles("test")
    @Import(BookServiceTestConfiguration .class)
    @RunWith(SpringRunner.class)
    public class BookServiceUnitTest {

        @Autowired
        private BookService bookService;

        // write unit tests
    }
для получения дополнительной информации читайте эту статью
...