使用Express/Mocha/Mongodb内存服务器进行单元测试



我想配置我的项目,以便为一些API端点(调用数据库(运行单元测试。我正在使用:

  • ExpressJS
  • MongoDB(无Mongoose(
  • Mocha/Chai
  • Mongodb内存服务器(模拟数据库(
// app.ts
export const app = express();
const port = process.env.PORT;
app.use("/my-route", myRoutes);
mongoConnect().then(() => {
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
});
// database.ts
export const mongoConnect = async () => {
try {
let MONGODB_URI = process.env.MONGODB_URI;
if (process.env.NODE_ENV === "test") {
const mongoServer = await MongoMemoryServer.create();
MONGODB_URI = mongoServer.getUri();
}
const client: MongoClient = await MongoClient.connect(MONGODB_URI);
_db = client.db("dbName");
_mongoClient = client;
if (process.env.NODE_ENV === "test") {
console.log("Connected to MongoDB Test");
} else {
console.log("Connected to MongoDB");
}
} catch (err) {
console.log("Error connecting to MongoDB:", err);
throw err;
}
};
export const getMongoClient = () => {
if (_mongoClient) {
return _mongoClient;
}
throw "Mongo client doesn't exist";
};
export const getDb = () => {
if (_db) {
return _db;
}
throw "No database found!";
};
// test.ts
let mongoClient: MongoClient;
let db: Db;
before(function (done) {
mongoConnect()
.then(() => {
db = getDb();
mongoClient = getMongoClient();
return db.createCollection("wordsCollection");
})
.then(() => {
db.collection("wordsCollection").insertMany(data);
})
.catch((err) => console.log(err))
.finally(() => done());
});
after(function (done) {
db.dropDatabase();
mongoClient.close().then(() => {
done();
});
});
it("test", async function () {
let res = await chai
.request(app)
.post("/my-route/hello")
.send({ excludeIds: [] });
expect(res.status).to.equal(200);
});
});

但它不起作用。。。

如果我在test.ts中调用mongoConnect((,它会console.log两次Connected to MongoDB Test。但如果我不调用该函数,它会抛出错误,因为MongoClient是未定义的。

我认为await chai.request(app)已经调用了数据库和服务器,但我之前需要创建Collection和Documents。所以我需要在测试之前连接到数据库。

如有任何帮助,我们将不胜感激。

我找到了一个解决方案,我不知道它是否是最佳实践,但它很有效,也很容易,这要归功于这篇文章:https://stackoverflow.com/a/70285190/10547153.

在连接到数据库和服务器之前,我需要在app.ts中添加一个条件,以便仅在Node自身调用时才启动它们。

if (require.main === module) {
mongoConnect().then(() => {
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
});
}

当文件直接从Node.js运行时,require.main设置为单元这意味着可以确定文件是否具有通过测试CCD_ 7直接运行。

现在我可以从test.ts连接到模拟数据库,并且只会触发一个连接。

最新更新