【问题标题】:unit testing - jest with supertest gives a timeout单元测试 - 与 supertest 开玩笑给出超时
【发布时间】:2018-11-27 05:16:06
【问题描述】:

我在运行单元测试时出错。我正在使用 NodeJS 的快速应用程序。我想测试返回消息(200)和(最终)函数的输出。

const {Router} = require('express');
const {query} = require('../dbConfig');

module.exports = (router = new Router()) => {
    //get only one user from the id
    router.post('/getUser', async (req,res)=>{
        id = req.body.id;
        sql = "SELECT lastname, firstname, email, title_id, id, state FROM users WHERE id=" + id;
        let result = await query(sql);
        if(result.length >= 1){
            res.send(result[0]);
        }

    })
    return router;
};

但是当我尝试运行以下测试时:

const app = require('../../app')
const request = require('supertest')
jest.mock('../../dbConfig');;

describe('POST /getUser', () => {
    let data = {
        id:1
    }

    it('Response 200 + response type',(done)=>{
        request.agent(app)
            .post('/getUser')
            .send(data)
            .expect(200, done)
    })
});

它返回以下错误

Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.

我尝试了不同的变体但没有成功...我还尝试了在线文档,但对这个错误并没有真正的帮助...我用npx jest 开玩笑,模拟文件看起来像这样:

const rep={
    "lastname": "admin",
    "firstname": "admin",
    "email": "admin@etsmtl.ca",
    "title_id": 1,
    "id": 1,
    "state": 1
};


const query = (sqli) =>{
    return new Promise((resolve, reject) =>{
        console.log("SQL request : " + sqli)
        if(sqli === "SELECT lastname, firstname, email, title_id, id, state FROM users WHERE id=1"){
            console.log("Passed")
            resolve(rep);
        }
    });

}

module.exports = {query};

【问题讨论】:

    标签: node.js unit-testing express jestjs supertest


    【解决方案1】:

    您的 query 方法返回一个对象 (rep),然后您在 POST 处理程序中检查它的长度。一个对象的长度是undefined,所以它没有达到res.send。您需要使用另一个 res.send 设置一个 else 选项,以便无论发生什么都会回答客户端。此外,您可能希望更改 POST 处理程序中的 if,或模拟文件中的返回格式。

    例如,在您的 Mock 文件中:

    const query = (sqli) =>{
        return new Promise((resolve, reject) =>{
            console.log("SQL request : " + sqli)
            if(sqli === "SELECT lastname, firstname, email, title_id, id, state FROM users WHERE id=1"){
                console.log("Passed")
                resolve([rep]); //Now it's an array of length 1, reaches the first send
            } else {
                reject([]); //Length is 0, so it will reach the second send
            }
        });
    
    }
    

    控制器

    if(result.length >= 1){
        res.send(result[0]);
    } else {
        res.status(500).send('Something broke!');
    }
    

    【讨论】:

    • 谢谢!我总是忘记考虑错误,但相信我,现在我会的!
    【解决方案2】:

    您确定您的数据库已初始化吗?你能在你的控制器上试试这个吗?

    router.post('/getUser', async (req,res)=>{
        id = req.body.id;
        sql = "SELECT lastname, firstname, email, title_id, id, state FROM users WHERE id=" + id;
        try {
           let result = await query(sql);
           if(result.length >= 1){
               res.send(result[0]);
           } else {
               res.sendStatus(404);
           }
        } catch(err) {
           res.sendStatus(500)
        }
    
    })
    

    如果您的数据库未正确初始化,或者查询抛出错误,它将永远不会响应

    【讨论】:

    • 实际上,正如您在测试中看到的那样,“查询”方法是模拟的。所以它只是出于测试目的而返回虚假数据。当我从邮递员那里尝试时,该功能也有效,所以只有单元测试有问题......
    • @etiennnr 好吧,你有超时的原因仍然是缺少 else/catch
    猜你喜欢
    • 2017-10-01
    • 1970-01-01
    • 2022-07-26
    • 2018-07-02
    • 2018-09-10
    • 2022-08-07
    • 2021-11-13
    • 2022-10-21
    • 1970-01-01
    相关资源
    最近更新 更多