使用 Junit 5 和 Micronaut 设置测试 MongoDBContainer
Posted
技术标签:
【中文标题】使用 Junit 5 和 Micronaut 设置测试 MongoDBContainer【英文标题】:Setting Test MongoDBContainer with Junit 5 and Micronaut 【发布时间】:2021-04-14 18:45:34 【问题描述】:尝试使用 Junit 5 和 micronaut 设置 Test MongoDBContainer,而不是在使用 application.yml 配置的测试环境中盯着随机端口上的 MongoDB。
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
方法的返回值来自 application.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);
【讨论】:
是否需要设置client = context.getBean(MongoClient.class);因为 MongoClient 在另一个项目中,我无权从另一个项目访问该项目。或者只添加到 ApplicationContext 就足够了 对我不起作用。在Checking status of localhost:49185
(当然是随机端口)之后我收到了:java.net.ConnectException: Connection refused: connect
【参考方案2】:
Micronaut 需要从 MongoDBContainer 获取连接 URL,因此使用 MicronautTest 无法像使用特殊“tc”数据库 URL 的 SQL 容器那样工作。 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())
...
【讨论】:
以上是关于使用 Junit 5 和 Micronaut 设置测试 MongoDBContainer的主要内容,如果未能解决你的问题,请参考以下文章
使用 Micronaut 应用程序为 JUnit5 中的每个单元/集成测试运行一次 TestContainer
在 JUnit 5 完成所有类测试后,测试容器未从 docker 中删除
处理 bean 注册时出错 [io.micronaut.rabbitmq.intercept.RabbitMQConsumerAdvice]