skip to Main Content

I am able to start the mongo image, insert and read data just fine using the snippet below. Similar to the redis example on testcontainers.org.

private static final int MONGO_PORT = 27017;

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

By default mongo doesn’t have credentials but I’m looking for a way to set the credentials so that my app’s MongoClient can get user/password from system properties and connect properly. I’ve tried adding the root user/password with the below but that didn’t set the credentials properly.

@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");

My question is: How can I start the test container with a username and password to allow my app to connect to it during my integration test using wiremock.

2

Answers


  1. Checking the docs you can have a GenericContainer rather than specifically a MongoDbContainer (not certain this makes much difference given it looks largely like I’ve got the same as what you’ve already tried)…

    I’ve then run:

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

    the logs from the container show:
    docker logs [container_id]:

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

    I can login successfully inside the container with my new administrative user:

    > 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()
    ---
    > 
    
    Login or Signup to reply.
  2. In short, you can find working example of test with MongoDB container here.

    To provide, more details: you can configure authentication to MongoDB test container by using GenericContainer and setting environment with following properties 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);
    

    Then you should use MongoClient with corresponding MongoCredential. For example, below is the test, that writes and reads document to/from MongoDB container.

    @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);
    }
    

    Notes:

    • To find more details on environment variables, you check documentation here (specifically, Environment Variables section)

    • To find more details on authenticated connection to MongoDB, you check documentation here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search