репозиторий всегда равен нулю после инициализации тестовых контейнеров

#mockito #testcontainers

Вопрос:

Я пытаюсь использовать TestingContainers. Я смог запустить его, но мои тесты всегда равны нулю. Я пытаюсь избежать насмешек, а скорее иметь реальные данные.

Репозиторий

 @Sql("classpath:data.sql")
class OrderDataRepositoryTest extends AbstractTestConfiguration {

    //@Mock
    @MockBean
    //@Autowired
    private OrderDataRepository orderRepository;

    private AutoCloseable closeable;

    @BeforeEach
    public void init() {
        closeable = MockitoAnnotations.openMocks(this);
    }

    @AfterEach
    void closeService() throws Exception {
        closeable.close();
    }

    @Test
    void getAllUsersTest() {
        List<Order> orders = orderRepository.findAll();
        orders.toString();
    }

}
 

конфигурация

 @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Testcontainers
public abstract class AbstractTestConfiguration {

    @Container
    private MySQLContainer database = new MySQLContainer("mysql:8.0");


    @Test
    public void test() {
        assertTrue(database.isRunning());
    }


}
 

Главная

 @SpringBootTest
@Sql("classpath:init.sql")
@TestPropertySource("classpath:application-test.yml")
class TentingContainerApplicationTests {

}
 

application.properties

 spring:
  application:
  datasource:
      url: jdbc:mysql:8.0:///test?TC_INITSCRIPT=file:src/main/resources/init.sql
      driver-class-name: com.mysql.jdbc.Driver
 

Закомментированный

 //@Mock
@MockBean
//@Autowired
 

это то, что я пробовал. Конечно, макет работает, но мне нужны реальные данные для классов @services и @repository.

совет?

Ответ №1:

Если вы хотите протестировать свой код, связанный с базой данных, изолированно (я предполагаю, что вы используете Spring Data JPA), тогда @DataJpaTest он идеально подходит.

Эта аннотация создаст для вас нарезанный контекст Spring, который содержит только компоненты, относящиеся к постоянству, такие как: DataSource , EntityManager , YourRepository . Это не включает ваши классы обслуживания, ваши @Component классы или @RestController .

По умолчанию эта аннотация пытается настроить встроенную базу данных в памяти как DataSource . Мы можем переопределить это (и вы уже сделали это с некоторыми примерами вашего кода) поведение для использования Testcontainers:

 @DataJpaTest
@Testcontainers
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class OrderDataRepositoryTest {
 
  @Container
  static MySQLContainer database = new MySQLContainer("mysql:8.0");
 
  @DynamicPropertySource
  static void setDatasourceProperties(DynamicPropertyRegistry propertyRegistry) {
    propertyRegistry.add("spring.datasource.url", database::getJdbcUrl);
    propertyRegistry.add("spring.datasource.password", database::getPassword);
    propertyRegistry.add("spring.datasource.username", database::getUsername);
  }
 
  @Autowired
  private OrderDataRepository orderRepository;
 
  @Test
  void shouldReturnOrders() {

  }
}
 

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

 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@Testcontainers

class MyIntegrationTest {
 
  @Container
  static MySQLContainer database = new MySQLContainer("mysql:8.0");
 
  @DynamicPropertySource
  static void setDatasourceProperties(DynamicPropertyRegistry propertyRegistry) {
    propertyRegistry.add("spring.datasource.url", database::getJdbcUrl);
    propertyRegistry.add("spring.datasource.password", database::getPassword);
    propertyRegistry.add("spring.datasource.username", database::getUsername);
  }

@Autowired
private ServiceA serviceA;

@Autowired
private OrderDataRepository orderDataRepository;
 
 

}

При работе с Spring TestContext для вашего теста и Mockito убедитесь, что понимаете разницу между @Mock и @MockBean .