使用凭据启动MongoDb测试容器

问题描述

我可以使用以下代码片段启动mongo图像,插入和读取数据。类似于testcontainers.org上的redis示例。

private static final int MONGO_PORT = 27017;

@ClassRule
public static MongoDBContainer mongo = new MongoDBContainer("mongo:3.2.4")
        .withExposedPorts(MONGO_PORT);

默认情况下,mongo没有凭据,但是我正在寻找一种设置凭据的方法,以便我的应用程序的MongoClient可以从系统属性中获取用户/密码并正确连接。我尝试在下面添加root用户/密码,但这没有正确设置凭据。

@ClassRule
public static MongoDBContainer mongo = new MongoDBContainer("mongo:3.2.4")
        .withExposedPorts(MONGO_PORT)
        .withEnv("MONGO_INITDB_ROOT_USERNAME","admin")
        .withEnv("MONGO_INITDB_ROOT_PASSWORD","admin");

我的问题是:我如何使用用户名和密码启动测试容器,以允许我的应用在使用Wiremock进行集成测试时连接到它。

解决方法

检查文档时,您可以使用GenericContainer而不是专门使用MongoDbContainer(由于我看起来和您已经尝试过的内容大致相同,因此不确定这有什么区别) ...

然后我运行:

private static final int MONGO_PORT = 27017;

    /**
     * https://hub.docker.com/_/mongo shows:
     *
     * $ docker run -d --network some-network --name some-mongo \
     *     -e MONGO_INITDB_ROOT_USERNAME=mongoadmin \
     *     -e MONGO_INITDB_ROOT_PASSWORD=secret \
     *     mongo
     */
    public static GenericContainer mongo = new GenericContainer(DockerImageName.parse("mongo:4.4.1"));

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("MONGO_INITDB_ROOT_USERNAME=mongoadministrator");
        list.add("MONGO_INITDB_ROOT_PASSWORD=secret");
        list.add("MONGO_INITDB_DATABASE=db");
        mongo.setEnv(list);
        mongo.withExposedPorts(MONGO_PORT);
        mongo.start();
    }

来自容器的日志显示: docker logs [container_id]

...
Successfully added user: {
    "user" : "mongoadministrator",<<<<<
    "roles" : [
        {
            "role" : "root","db" : "admin"
        }
    ]
}
...

我可以使用新的管理用户成功登录容器内

> docker exec -it 3ae15f01074c bash
Error: No such container: 3ae15f01074c

> docker ps -a
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                      NAMES
755e214f23d6        mongo:4.4.1                 "docker-entrypoint.s…"   2 seconds ago       Up 2 seconds        0.0.0.0:32803->27017/tcp   elegant_keldysh
cdb4f55930f4        testcontainers/ryuk:0.3.0   "/app"                   3 seconds ago       Up 3 seconds        0.0.0.0:32802->8080/tcp    testcontainers-ryuk-ef84751e-bfd4-41eb-b381-1c1206186eda

> docker exec -it 755e214f23d6 bash
root@755e214f23d6:/# mongo admin -u mongoadministrator
MongoDB shell version v4.4.1
Enter password:                      <<<<<<<<<<<<<<<< BAD PASSWORD ENTERED HERE
connecting to: mongodb://127.0.0.1:27017/admin?compressors=disabled&gssapiServiceName=mongodb
Error: Authentication failed. :
connect@src/mongo/shell/mongo.js:374:17
@(connect):2:6
exception: connect failed
exiting with code 1

root@755e214f23d6:/# mongo admin -u mongoadministrator
MongoDB shell version v4.4.1
Enter password:                   <<<<<<<< GOOD PASSWORD secret ENTERED HERE
connecting to: mongodb://127.0.0.1:27017/admin?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("63279398-d9c6-491d-9bd9-6b619dc4a99d") }
MongoDB server version: 4.4.1
Welcome to the MongoDB shell.
For interactive help,type "help".
For more comprehensive documentation,see
    https://docs.mongodb.com/
Questions? Try the MongoDB Developer Community Forums
    https://community.mongodb.com
---
The server generated these startup warnings when booting: 
        2020-10-24T22:06:24.914+00:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
---
---
        Enable MongoDBs free cloud-based monitoring service,which will then receive and display
        metrics about your deployment (disk utilization,CPU,operation statistics,etc).

        The monitoring data will be available on a MongoDB website with a unique URL accessible to you
        and anyone you share the URL with. MongoDB may use this information to make product
        improvements and to suggest MongoDB products and deployment options to you.

        To enable free monitoring,run the following command: db.enableFreeMonitoring()
        To permanently disable this reminder,run the following command: db.disableFreeMonitoring()
---
> 
,

简而言之,您可以找到使用MongoDB容器here进行测试的有效示例。

要提供更多详细信息:您可以使用GenericContainer并使用以下属性MONGO_INITDB_ROOT_USERNAME,MONGO_INITDB_ROOT_PASSWORD设置环境来配置对MongoDB测试容器的身份验证:

@ClassRule
public static final GenericContainer<?> MONGODB = new GenericContainer<>(DockerImageName.parse(MONGO_IMAGE))
        .withEnv("MONGO_INITDB_ROOT_USERNAME",USERNAME)
        .withEnv("MONGO_INITDB_ROOT_PASSWORD",PASSWORD)
        .withEnv("MONGO_INITDB_DATABASE",TEST_DATABASE)
        .withExposedPorts(MONGO_PORT);

然后,您应将MongoClient与相应的MongoCredential一起使用。例如,下面是测试,该测试在MongoDB容器中读写文件。

@Test
public void shouldWriteAndReadMongoDocument() {
    ServerAddress serverAddress = new ServerAddress(MONGODB.getHost(),MONGODB.getMappedPort(MONGO_PORT));
    MongoCredential credential = MongoCredential.createCredential(USERNAME,AUTH_SOURCE_DB,PASSWORD.toCharArray());
    MongoClientOptions options = MongoClientOptions.builder().build();

    MongoClient mongoClient = new MongoClient(serverAddress,credential,options);
    MongoDatabase database = mongoClient.getDatabase(TEST_DATABASE);
    MongoCollection<Document> collection = database.getCollection(TEST_COLLECTION);

    Document expected = new Document("name","foo").append("foo",1).append("bar","string");
    collection.insertOne(expected);

    Document actual = collection.find(new Document("name","foo")).first();
    assertThat(actual).isEqualTo(expected);
}

注释:

  • 要查找有关环境变量的更多详细信息,请查看文档here(特别是环境变量部分)

  • 要查找有关与MongoDB进行身份验证的连接的更多详细信息,请查看文档here

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...