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

问题描述

我正在努力更好地为我的 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”作为参数传递。
  • restaurantstest_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,这似乎更容易设置和拆除测试数据库。谢谢,如果需要更多信息,请告诉我。

解决方法

由于您有两个数据库,restaurantstest_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"
  },

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...