无法在测试环境中连接到 mongoose

Can't connect to mongoose on test environment

我在 docker 中有一个节点应用程序 运行ning 和 mongodb,它在开发环境中运行良好。但是,我正在使用 mocha 和 chai 创建一些测试,当我 运行 这些测试时我无法连接到 mongo。

我要测试的功能是:

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

我的测试:

/* 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: "test@example.com",
      },
      source: "CREDIT_CARD",
    };
    const result = await CreateDonation.run(context);
    console.log(result);
    done();
  });
});

我的数据库配置文件:

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;

我从上面的测试得到的错误是:

MongooseServerSelectionError: getaddrinfo ENOTFOUND db

我做错了什么?我是否缺少导入内容?

刚发现在测试时,我需要在 mongo 的连接字符串上使用“localhost”(我使用的是 docker-compose 中的名称)。因此,使用 URI 作为“mongodb://localhost:27017/donations”它起作用了。不知道为什么。

当您使用 docker 撰写文件 运行 您在 docker 中的服务时,他们将根据您为 [=46] 中的服务编写的名称获得主机名=]-撰写文件。

示例:

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

在此示例中,web 服务可以访问位于 redis hostname 的 redis 数据库。

如果您以这种方式更改服务名称:

  db:
    image: "redis:alpine"

Web 服务必须连接到 db 主机。

因此,当您 运行 撰写文件时,您的 db 服务会通过您的应用程序服务的 db 主机名访问。但是当你 运行 你的测试在 docker 之外组合时,db 主机名不可用,你需要使用 localhost 因为你的数据库 运行ning 在你的 OS 直接(或者它是 运行ning 在容器内,27017 端口映射到主主机上)。

如果您使用的是 unix OS,您可以通过在 /etc/hosts 文件中添加别名来解决问题:

127.0.0.1 localhost db

通过这种方式,您可以 运行 您的测试保持 db 连接字符串。

否则,这是建议的解决方案,您可以使用环境变量在应用程序启动时更改连接字符串:

mongoose.connect(process.env.MONGO_URI)

并且运行它使用

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

然后在 docker compose 中,您可以使用以下代码添加一个固定的环境变量:

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