#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 .