GabrielaGuedes
GabrielaGuedes

Reputation: 27

Can't connect to mongoose on test environment

I have a node application running in docker with mongodb and it works fine on development environment. However, I'm creating some tests with mocha and chai and I can't connect to mongo when I run these tests.

The function I want to test is:

const Interactor = require("interactor");
const Donation = require("../models/donations");

module.exports = class CreateDonation extends Interactor {
  async run(context) {
    this.context = context;
    this.donation = new Donation.Model({
      donationId: context.id,
      status: context.status,
      amount: context.chargeInfo.donatedValue,
      donatorEmail: context.donatorInfo.email,
      source: context.source,
    });

    await this.donation.save();
  }

  rollback() {
    Donation.Model.findOneAndRemove({ donationId: this.context.id });
  }
};

My test:

/* eslint-disable no-unused-vars */
/* eslint-disable no-undef */
const chai = require("chai");
const chaiHttp = require("chai-http");
const CreateDonation = require("../../interactors/create-donation");
require("../../config/db");

const should = chai.should();
const { expect } = chai;

chai.use(chaiHttp);

describe("CreateDonation", () => {
  it("Creates a donation when context passed is correct", async (done) => {
    const context = {
      id: "123123",
      status: "AUTHORIZED",
      chargeInfo: {
        donatedValue: 25.0,
      },
      donatorInfo: {
        email: "[email protected]",
      },
      source: "CREDIT_CARD",
    };
    const result = await CreateDonation.run(context);
    console.log(result);
    done();
  });
});

My db config file:

const mongoose = require("mongoose");
require("dotenv/config");

mongoose
  .connect("mongodb://db:27017/donations", {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    reconnectInterval: 5000,
    reconnectTries: 50,
  })
  .then(() => {
    console.log("good");
  })
  .catch((err) => {
    console.log(err);
  });
mongoose.Promise = global.Promise;

module.exports = mongoose;

The error I get from the test above is:

MongooseServerSelectionError: getaddrinfo ENOTFOUND db

What am I doing wrong? Am I missing to import something?

Upvotes: 0

Views: 385

Answers (2)

lifeisfoo
lifeisfoo

Reputation: 16344

When you run your services inside docker with a docker compose file, they'll get an hostname based on the name you wrote for the service inside the docker-compose file.

Example:

version: "3.9"
services:
  web:
    build: .
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"

In this example, the web service can reach the redis db at the redis hostname.

If you change the service name in this way:

  db:
    image: "redis:alpine"

The web service must connect to the db host.

So, when you run the compose file, your the db service is reached with the db hostname from you app service. But when you run your tests outside a docker compose, the db hostname isn't available and you need to use localhost because your db is running on your OS directly (or it is running inside a container with the 27017 port mapped on the main host).

If you're using a unix OS, you can solve your problem adding an alias in your /etc/hosts file:

127.0.0.1 localhost db

In this way you can run your tests keeping the db connection string.

Otherwise, and this is the suggested solution, you can use an environment variable to change the connection string at the application startup:

mongoose.connect(process.env.MONGO_URI)

And run it using

MONGO_URI=mongodb://db:27017/donations npm start

Then in the docker compose you can add a fixed environment variable using this code:

environment:
  - MONGO_URI=mongodb://db:27017/donations

Upvotes: 1

GabrielaGuedes
GabrielaGuedes

Reputation: 27

Just found out that when testing, I need to use "localhost" on my connection string for mongo (I was using the name from docker-compose). So with the URI as "mongodb://localhost:27017/donations" it worked. I don't know why.

Upvotes: 0

Related Questions