在 Micronaut 应用程序中使用 TestContainer 的测试环境的 ApplicationContext 不起作用

Posted

技术标签:

【中文标题】在 Micronaut 应用程序中使用 TestContainer 的测试环境的 ApplicationContext 不起作用【英文标题】:ApplicationContext for Test environment using TestContainer in Micronaut application not working 【发布时间】:2021-10-17 15:49:48 【问题描述】:

我正在尝试使用 MongoDb 和 RabbitMQ 测试容器测试 Micronaut 应用程序。 application.yml 具有以下配置

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

我有下面的配置代码

@Introspected
@ConfigurationProperties("mongodb")
public record MongodbConfiguration(@NotNull String uri, @NotNull String database) 

在存储库中。存储库在另一个项目中

@Singleton
    public record Repository(MongoClient mongoClient, MongodbConfiguration mongodbConfiguration) implements IRepository 
    @Override
    public <T> MongoCollection<T> getCollection(String collectionName, Class<T> typeParameterClass) 
        return mongoClient
                .getDatabase(mongodbConfiguration.database())
                .getCollection(collectionName, typeParameterClass);
    

mongodbConfiguration.uri 始终是mongodb://localhost:27017,但是在 JUnit 测试中我有以下代码

@Testcontainers
public abstract class TestContainerFixture 
    public static final GenericContainer mongoDBContainer;
    public static final GenericContainer rabbitMQContainer;

    static 
        mongoDBContainer = new GenericContainer(DockerImageName.parse("mongo:4.0.10")).withExposedPorts(27017);
        rabbitMQContainer = new GenericContainer(DockerImageName.parse("rabbitmq:3-management-alpine")).withExposedPorts(5672);
        mongoDBContainer.start();
        rabbitMQContainer.start();
    


@MicronautTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class DiscountDeleteListenerTest extends TestContainerFixture 
    
    private ApplicationContext applicationContext;

@BeforeAll
@DisplayName("Initial application setup")
void initialApplicationSetup() 
    applicationContext = ApplicationContext.run(
            Map.of("mongodb.uri",
                    String.format("mongodb://%s:%s", mongoDBContainer.getContainerIpAddress(), mongoDBContainer.getMappedPort(27017)),
                    "rabbitmq.uri",
                    String.format("amqp://%s:%s", rabbitMQContainer.getContainerIpAddress(), rabbitMQContainer.getMappedPort(5672)))
            , "test"
    );
    iDiscountProducer = applicationContext.getBean(IDiscountProducer.class);


下面的代码很好

String.format("mongodb://%s:%s", mongoDBContainer.getContainerIpAddress(), mongoDBContainer.getMappedPort(27017)) 

这会将 URL 设为 mongodb://localhost:57032

现在,当我完成所有单元测试并检查数据库时,它正在从本地 docker 实例(端口 27017)插入、更新和删除

集群的主机仍然指向 27017

从这里https://github.com/micronaut-projects/micronaut-test/issues/32 得到了一些想法,但仍然不知道该怎么做。

【问题讨论】:

可能是个意外,但现在我处于同样的情况,我认为是因为我们不能同时使用 MicronautTest 和 TestContainer。当您使用 MicronautTest 注释测试时,它会在调用您的初始化方法之前唤醒应用程序,但这只是一个假设 不确定Micronaut,但是如果它使用默认的自动配置,那么你需要排除MongoAutoConfiguration并手动创建一个mongo客户端,否则它会指向默认配置的MongoDB 【参考方案1】:

我们不能同时使用 MicronautTest 和 TestContainer。当您使用 MicronautTest 注释测试时,它会在调用您的初始化方法之前唤醒应用程序

所以删除@MicronautTest 解决问题

【讨论】:

以上是关于在 Micronaut 应用程序中使用 TestContainer 的测试环境的 ApplicationContext 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

在 micronaut 中覆盖未找到的异常处理程序

Micronaut 教程:如何使用基于 JVM 的框架构建微服务?

如何解决 micronaut 应用程序中的错误“没有 [io.micronaut.data.operations.PrimaryRepositoryOperations] 类型的 bean”?

Micronaut 禁止所有路线

使用 Micronaut 应用程序为 JUnit5 中的每个单元/集成测试运行一次 TestContainer

在 Jetty 未按预期工作的情况下在 micronaut 上启用 HTTPS 支持