Вопрос или проблема
Я хочу провести простой тест MongoDB одного из MongoRepository. Для этого я использовал @DataMongoTest
@DataMongoTest(
excludeAutoConfiguration = {
HibernateJpaAutoConfiguration.class,
DataSourceAutoConfiguration.class
}
)
@EnableMongoRepositories
class BookingMongoRepositoryTest {
@Autowired
private BookingMongoRepository bookingMongoRepository;
@Test
void testSaveAndFindBooking() {
BookingDocument document = buildBookingDocument();
BookingDocument savedDocument = bookingMongoRepository.save(document);
Optional<BookingDocument> retrievedBooking = bookingMongoRepository.findById(savedDocument.get_id());
assertNotNull(retrievedBooking);
assertThat(retrievedBooking.get().getIdAccount()).isEqualTo(1L);
}
private BookingDocument buildBookingDocument() {
TicketDocument ticketDocument1 = TicketDocument.builder()
.idFlight("1")
.idPassenger(1L)
.seat("10A")
.price(new BigDecimal("62.25"))
.build();
TicketDocument ticketDocument2 = TicketDocument.builder()
.idFlight("1")
.idPassenger(2L)
.seat("10B")
.price(new BigDecimal("62.25"))
.build();
BookingDocument bookingDocument = BookingDocument.builder()
.bookingPrice(new BigDecimal("124.50"))
.idAccount(1L)
.tickets(List.of(ticketDocument1, ticketDocument2))
.build();
bookingDocument.setStatus("ACTIVE");
return bookingDocument;
}
}
Я исключил автоконфигурацию для Hibernate и JPA, но все равно получаю исключение, связанное с ошибкой создания bean JpaRepository:
Исключение:
Причина: org.springframework.beans.factory.BeanCreationException: Ошибка создания bean с именем ‘passengerJpaRepository’, определенного в io.github.paulmarcelinbejan.coandaairlines.reservationsystem.adapters.outbound.repository.jpa.PassengerJpaRepository, определенном в @EnableJpaRepositories, объявленном в CoandaAirlinesReservationSystemApplication: Невозможно разрешить ссылку на bean ‘jpaSharedEM_entityManagerFactory’ при установке свойства bean ‘entityManager’
Причина: org.springframework.beans.factory.BeanCreationException: Ошибка создания bean с именем ‘jpaSharedEM_entityManagerFactory’: Невозможно разрешить ссылку на bean ‘entityManagerFactory’ при установке аргумента конструктора
Причина: org.springframework.beans.factory.NoSuchBeanDefinitionException: Не существует bean с именем ‘entityManagerFactory’
Мое SpringBootApplication:
@SpringBootApplication
@EnableConfigurationProperties
@ComponentScan({ "io.github.paulmarcelinbejan*" })
@EntityScan({ "io.github.paulmarcelinbejan*" })
@EnableJpaRepositories({ "io.github.paulmarcelinbejan*" })
@EnableMongoRepositories({ "io.github.paulmarcelinbejan*" })
@EnableFeignClients({ "io.github.paulmarcelinbejan*" })
public class CoandaAirlinesReservationSystemApplication extends AbstractApplication {
public static void main(String[] args) {
SpringApplication.run(CoandaAirlinesReservationSystemApplication.class, args);
}
}
Ответ или решение
Использование аннотации @DataMongoTest
для тестирования MongoRepository
является хорошей практикой для изолированного тестирования работы с базой данных MongoDB в приложениях Spring. В вашем коде видно, что вы правильно настроили аннотацию, но столкнулись с исключением, связанным с JpaRepository
, что может означать, что конфигурация не совсем корректна. Давайте разберемся.
-
Настройка
@DataMongoTest
: Когда вы используете аннотацию@DataMongoTest
, она предполагает, что вы хотите тестировать только MongoDB, а не JPA или Hibernate. Соответственно, вам не нужно настраивать@EnableJpaRepositories
, что может вызвать конфликты при автосканировании бинов и конфигурации контекста. -
Исключение недостающих конфигураций: Убедитесь, что вы исключили все нежелательные автоконфигурации, чтобы избежать конфликтов. Вы уже исключили конфигурации Hibernate и DataSource, но возможно, что другие компоненты, такие как репозитории JPA, всё ещё автонастраиваются из-за ваших аннотаций в основном классе приложения.
-
Изменение основного класса приложения: Я рекомендую убрать аннотацию
@EnableJpaRepositories
из основного класса приложения. Если вы планируете тестировать только MongoDB, это поможет избежать ненужных конфликтов.
Вот исправленный основной класс приложения без JPA:
@SpringBootApplication
@EnableConfigurationProperties
@ComponentScan({ "io.github.paulmarcelinbejan*" })
@EntityScan({ "io.github.paulmarcelinbejan*" }) // Это можно оставить, если нужны сущности JPA, но исключите JPA репозитории
@EnableMongoRepositories({ "io.github.paulmarcelinbejan*" })
@EnableFeignClients({ "io.github.paulmarcelinbejan*" })
public class CoandaAirlinesReservationSystemApplication extends AbstractApplication {
public static void main(String[] args) {
SpringApplication.run(CoandaAirlinesReservationSystemApplication.class, args);
}
}
-
Проверка конфигурации репозитория: Убедитесь, что ваш репозиторий имеет такую же структуру пакетов, как и указано в
@EnableMongoRepositories
. Это позволит Spring корректно обнаружить и настроить вашBookingMongoRepository
. -
Тестирование: Вот пример, как должен выглядеть ваш тест, без необходимости в изменениях:
@DataMongoTest
class BookingMongoRepositoryTest {
@Autowired
private BookingMongoRepository bookingMongoRepository;
@Test
void testSaveAndFindBooking() {
BookingDocument document = buildBookingDocument();
BookingDocument savedDocument = bookingMongoRepository.save(document);
Optional<BookingDocument> retrievedBooking = bookingMongoRepository.findById(savedDocument.get_id());
assertNotNull(retrievedBooking);
assertThat(retrievedBooking.get().getIdAccount()).isEqualTo(1L);
}
private BookingDocument buildBookingDocument() {
TicketDocument ticketDocument1 = TicketDocument.builder()
.idFlight("1")
.idPassenger(1L)
.seat("10A")
.price(new BigDecimal("62.25"))
.build();
TicketDocument ticketDocument2 = TicketDocument.builder()
.idFlight("1")
.idPassenger(2L)
.seat("10B")
.price(new BigDecimal("62.25"))
.build();
BookingDocument bookingDocument = BookingDocument.builder()
.bookingPrice(new BigDecimal("124.50"))
.idAccount(1L)
.tickets(List.of(ticketDocument1, ticketDocument2))
.build();
bookingDocument.setStatus("ACTIVE");
return bookingDocument;
}
}
Заключение
Проблемы с созданием бинов JPA следует решать, убирая автоконфигурации и аннотации, относящиеся к JPA, с учётом того, что вы хотите тестировать только MongoDB. После этих изменений ваш код должен заработать корректно. Если всё еще будут проблемы, стоит внимательно проверить другие зависимости проекта или настройки, которые могут вызывать конфликт.