Запись модульного теста в SpringBoot без запуска приложения

#spring-boot #junit

#весенняя загрузка #junit

Вопрос:

Я разрабатываю микросервисы в SpringBoot. Я пишу модульный тест для уровня сервиса и DAO. Когда я использую @SpringBootTest, он запускает приложение при сборке. Но он не должен запускать приложение при запуске модульного теста. Я использовал @RunWith (SpringRunner.class ), Но я не могу получить экземпляр класса @Autowired в классе junit. Как я могу настроить тестовый класс junit, который не должен запускать приложение, и как @Autowired экземпляр класса в классе junit.

Ответ №1:

Используйте MockitoJUnitRunner для тестирования JUnit5, если вы не хотите запускать полное приложение.

Любая служба, репозиторий и интерфейс могут быть подделаны аннотацией @Mock.

@InjectMocks используется над объектом класса, который необходимо протестировать.

Вот пример этого.

 @RunWith(MockitoJUnitRunner.class)
@SpringBootTest
public class AServiceTest {
    
    @InjectMocks
    AService aService;
    
    @Mock
    ARepository aRepository;
    
    @Mock
    UserService userService;
    
    
    @Before
    public void setUp() {
        // MockitoAnnotations.initMocks(this);
        // anything needs to be done before each test.
    }
    
    @Test
    public void loginTest() {
        Mockito.when(aRepository.findByUsername(ArgumentMatchers.anyString())).thenReturn(Optional.empty());
        String result = aService.login("test");
        assertEquals("false", result);
    }
  

Комментарии:

1. Требованием должно быть подключение к базе данных для извлечения записей. Если макет объекта, мы не можем получить данные в реальном времени. Возможно ли это с помощью @ContextConfiguration

2. @user3410249 если вы хотите выполнить модульное тестирование, вы можете издеваться над самими записями базы данных. Поскольку MockitoJUnitRunner — это самый быстрый способ выполнить тесты, он тестирует без запуска приложения или внешних БД. Вариант заключается в том, что вы можете использовать Mockito.when(…).thenReturn() для возврата измененных записей из базы данных, что является лучшим способом для модульного тестирования. Но если вы хотите подключиться к БД в реальном времени, ваше приложение запустится.

3. Спасибо. Я стал лучше понимать.

Ответ №2:

С помощью Spring Boot вы можете запустить сокращенную версию своего приложения для своих тестов. Это создаст контекст Spring, который содержит только подмножество ваших компонентов, которые актуальны, например, только для вашего веб-уровня (контроллеры, фильтры, конвертеры и т. Д.): @WebMvcTest .

Существует аналогичная аннотация, которая может помочь вам протестировать ваши DAO, поскольку она заполняет только компоненты, относящиеся к JPA и базе данных (например EntitiyManager , Datasource , и т.д.): . @DataJpaTest

Если вы хотите автоматически подключить компонент, который не является частью контекста Spring Test, который создается аннотацией выше, вы можете использовать a @TestConfiguration для ручного добавления любых компонентов, которые вам нравятся, в контекст теста

 @WebMvcTest(PublicController.class)
class PublicControllerTest {

  @Autowired
  private MockMvc mockMvc;

  @TestConfiguration
  static class TestConfig {

    @Bean
    public EntityManager entityManager() {
      return mock(EntityManager.class);
    }

    @Bean
    public MeterRegistry meterRegistry() {
      return new SimpleMeterRegistry();
    }

  }
}
  

Ответ №3:

В зависимости от ваших настроек тестирования, если вы не хотите автоматически подключать макет, а «реальную вещь», вы можете просто аннотировать свой тестовый класс, чтобы включить именно те классы, которые вам нужны (плюс их транзитивные зависимости, если необходимо)

Например :

 @SpringJUnitConfig({ SimpleMeterRegistry.class })
  

или

 @SpringJUnitConfig
@Import({ SimpleMeterRegistry.class })
  

или

 @SpringJUnitConfig
@ContextConfiguration(classes = { SimpleMeterRegistry.class })
  

Смотрите рабочие образцы на основе JUnit5 здесь Spring Boot Web Data JDBC allin .