问题描述
我正在努力更好地为我的 Node.js API 编写测试。我的最新项目让我查询端点 /api/v1/restaurants
,该端点返回包括对象数组的数据。这是控制器内的功能调用:
restaurantRouter.get("/api/v1/restaurants",async (req,res) => {
try {
// const results = await db.query("SELECT * FROM restaurants");
const results = await select("restaurants");
res.status(200).json({
status: "success",results: results.rows.length,data: {
restaurants: results.rows
}
})
} catch (err) {
console.log(err)
}
})
- 如您所见,我已将数据库查询抽象到一个单独的实用程序页面,但我仍将表名“restaurants”作为参数传递。
-
restaurants
和test_restaurants
表都是在同一个数据库中的本地驱动器上创建和运行的。
当我尝试在测试中进行 API 调用时,我的问题就出现了:
test("restaurants are returned as JSON",async () => {
await api
.get("/api/v1/restaurants")
.expect(200)
.expect('Content-Type',/application\/json/)
})
test("all restaurants are returned",async () => {
const response = await api.get("/api/v1/restaurants")
expect(response.body.data).not.toBeEmpty()
expect(response.body.data.restaurants).toBeArrayOfSize(2)
})
它们立即默认为 Dev 数据库表 restaurants
。我的直接想法是做简单/懒惰的事情,并为这样的测试创建相同的路线:
restaurantRouter.get("/api/v1/test-restaurants",res) => {
try {
const results = await select("test_restaurants");
res.status(200).json({
status: "success",data: {
restaurants: results.rows
}
})
} catch (err) {
console.log(err)
}
})
是否有更好或更优雅的方法来测试这些?也许使用中间件传入一个可选变量,如果没有给出变量参数,默认为 Dev/Prod 数据库?
我已经搜索了几天,所有教程和示例都有人使用 mongoDB,这似乎更容易设置和拆除测试数据库。谢谢,如果需要更多信息,请告诉我。
解决方法
由于您有两个数据库,restaurants
和 test_restaurants
。
在 package.json 中编辑您的测试命令
"test": "cross-env NODE_ENV=test jest"
。
如果 test_restaurants
在您的配置中进行测试,则让您的应用使用 NODE_ENV
数据库。
if(process.env.NODE_ENV === "test"){
// use test database
}
if(process.env.NODE_ENV !== "test"){
// use production database
}
,
为了更清楚地说明我如何使用@Odunsi 的回答:
我的 db/index.js
文件:
const { Pool } = require("pg")
const PG_DATABASE = process.env.NODE_ENV === "test"
? process.env.TEST_DATABASE
: process.env.DEV_DATABASE
const pool = new Pool({
user: process.env.PGUSER,host: process.env.PGHOST,database: PG_DATABASE,port: 5432,password: null
})
pool.on('connect',() => {
console.log(`Connected to the DB: ${process.env.NODE_ENV}`);
});
module.exports = {
query: (text,params) => pool.query(text,params)
}
密钥通过脚本传入 NODE_ENV
(如上面的答案所示),但我不必使用 cross-env
模块。
"scripts": {
"test": "NODE_ENV=test jest --verbose --runInBand","dev": "NODE_ENV=development nodemon index.js"
},
现在我使用两个不同的数据库。