使用凭据启动 MongoDb 测试容器
Start MongoDb Test Container with credentials
我可以使用下面的代码片段启动 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 可以从系统属性中获取 user/password 并正确连接。我试过用下面的方法添加根 user/password 但没有正确设置凭据。
@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
并使用以下属性设置环境来为 MongoDB 测试容器配置身份验证 MONGO_INITDB_ROOT_USERNAME, MONGO_INITDB_ROOT_PASSWORD
:
@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
。例如,下面是写入和读取文档 to/from 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);
}
备注:
我可以使用下面的代码片段启动 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 可以从系统属性中获取 user/password 并正确连接。我试过用下面的方法添加根 user/password 但没有正确设置凭据。
@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
并使用以下属性设置环境来为 MongoDB 测试容器配置身份验证 MONGO_INITDB_ROOT_USERNAME, MONGO_INITDB_ROOT_PASSWORD
:
@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
。例如,下面是写入和读取文档 to/from 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);
}
备注: