无法在测试环境中连接到 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
我在 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