簡體   English   中英

使用 Junit 5 和 Micronaut 設置測試 MongoDBContainer

[英]Setting Test MongoDBContainer with Junit 5 and Micronaut

嘗試使用 Junit 5 和 micronaut 設置測試 MongoDBContainer,而不是在使用 application.yml 配置的測試環境上的隨機端口上盯着 MongoDB。

應用程序.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

您開始的測試容器綁定了一個隨機端口,您需要手動將其提供給 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);
    }

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

    ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM