在 postgreSQL 中使用测试数据库更好地测试 Express 路由

Better testing Express routes with test DB in postgreSQL

我正努力在为我的 Node.js API 编写测试方面做得更好。我的最新项目让我查询一个端点 /api/v1/restaurants,其中 returns 数据包括一个对象数组。这是控制器内的功能调用:

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

当我尝试在我的测试中进行 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 数据库 table restaurants。我的直接想法是只做 easy/lazy 事情并为这样的测试创建一个相同的路径:

restaurantRouter.get("/api/v1/test-restaurants", async (req, res) => {
    try {
        const results = await select("test_restaurants");

        res.status(200).json({
            status: "success",
            results: results.rows.length,
            data: {
                restaurants: results.rows
            }
        })
    } catch (err) {
        console.log(err)
    }

})

是否有更好或更优雅的方法来测试这些?如果没有给出变量参数,也许使用中间件传递默认为 Dev/Prod 数据库的可选变量?

我这几天一直在搜索,所有教程和示例都有人使用 mongoDB,这似乎更容易设置和拆除测试数据库。谢谢,如果需要更多信息,请告诉我。

因为您有两个数据库,restaurantstest_restaurants

在 package.json

中编辑您的测试命令

"test": "cross-env NODE_ENV=test jest".

如果 NODE_ENV 在您的配置中进行测试,则让您的应用使用 test_restaurants 数据库。

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"
  },

现在我使用两个不同的数据库。