Настройка тестового MongoDBContainer с помощью Junit 5 и Micronaut

#java #junit #micronaut #testcontainers #micronaut-test

#java #junit #micronaut #тестовые контейнеры #micronaut-тест

Вопрос:

Попытка настроить тестовый MongoDBContainer с Junit 5 и micronaut вместо того, чтобы смотреть MongoDB на случайный порт в тестовой среде, он использует приложение.конфигурация yml.

application.yml

 micronaut:
  application:
    name: feteBirdProductConsumer

mongodb:
  uri: "mongodb://${MONGO_HOST:localhost}:${MONGO_PORT:27017}"
  database: "FeteBird-Product"
 

Тест Junit

 @MicronautTest
@Testcontainers
public class ProductListenerTest {
    private final IProductProducer iProductProducer;
    @Container
    private final MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10"));

    public ProductListenerTest(IProductProducer iProductProducer) {
        this.iProductProducer = iProductProducer;
    }

    @BeforeEach
    @DisplayName("Mongo Db container starting")
    void mongoDbContainerStarting() {
        mongoDBContainer.start();
    }

    @Test
    @DisplayName("Check if Mongo db container is up")
    void checkIfMongoDbContainerIsUp() {
        Assertions.assertTrue(mongoDBContainer.isRunning());
    }


    @Test
    @DisplayName("Should search based on the name")
    void shouldSearchBasedOnTheName() {
        iProductProducer.findFreeText("string").subscribe(item -> {
            System.out.println(item);
        });
    }
}
 

В shouldSearchBasedOnTheName методе возвращаемое значение берется из приложения.конфигурация yml MongoDB.

В тестовой среде я не вставил никакого значения в MongoDB, но этот метод возвращает значение из приложения MongoDB

Я думаю, что мне не хватает конфигурации для MongoDB, но я совершенно не уверен, как настроить

Обновить

 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class ProductListenerTest implements TestPropertyProvider {
@Nonnull
    @Override
    public Map<String, String> getProperties() {
        mongoDBContainer.start();
        String address = mongoDBContainer.getHost();
        Integer port = mongoDBContainer.getFirstMappedPort();
        return CollectionUtils.mapOf(
                "MONGO_HOST", address,
                "MONGO_PORT", port
        );
    }
}
 

Исключение

 com.mongodb.MongoSocketReadException: Prematurely reached end of stream
 

Ответ №1:

Тестовый контейнер, который вы запускаете, привязывает случайный порт, который вам нужно вручную передать в Micronaut, автоматической интеграции между ними нет. Я не думаю, что вы сможете выполнить это, используя @MicronautTest , поскольку он запускает контекст приложения еще до инициализации контейнера. Однако вы все равно можете настроить и запустить контекст самостоятельно:

 @Testcontainers
public class ProductListenerTest {
    @Container
    private MongoDBContainer mongoDBContainer = 
                     new MongoDBContainer(DockerImageName.parse("mongo:4.0.10"));
    private ApplicationContext context;
    private MongoClient client;

    @BeforeEach
    void mongoDbContainerStarting() {
        mongoDBContainer.start();
        // Overwrite the mongodb.uri value from your configuration file
        context = ApplicationContext.run(
                      Map.of("mongodb.uri", mongoDBContainer.getReplicaSetUrl()));
        client = context.getBean(MongoClient.class);
    }
 

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

1. Нужно ли мне устанавливать client = context.getBean(MongoClient.class ); потому что MongoClient находится в другом проекте, и у меня нет доступа к этому проекту из другого проекта. Или достаточно просто добавить в ApplicationContext

2. У меня это не работает. После Checking status of localhost:49185 (конечно, случайный порт) Я получил: java.net.ConnectException: Connection refused: connect

Ответ №2:

Micronaut необходимо получить URL-адрес подключения от MongoDBContainer, поэтому использование MicronautTest не будет работать так, как с контейнерами SQL, которые используют специальные URL-адреса базы данных «tc». Ответ JUnit аналогичен тому, что я использовал для Spock,

 @Testcontainers
class MongoControllerSpec extends Specification {

    @Shared
    MongoDBContainer mongo = new MongoDBContainer("mongo:4.1.1")
            .withExposedPorts(27017)

    @Shared
    @AutoCleanup
    EmbeddedServer embeddedServer

    @Shared
    @AutoCleanup
    RxHttpClient rxClient

    def setupSpec() {
        embeddedServer = ApplicationContext.run(EmbeddedServer,
                ['mongodb.uri': mongo.getReplicaSetUrl("micronaut")])
        rxClient = embeddedServer.applicationContext.createBean(RxHttpClient, embeddedServer.getURL())
    }

    ...
}