#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())
}
...
}