【问题标题】:How to wait for a mongoose .exec() callback to finish executing before testing for express response object?如何在测试快速响应对象之前等待 mongoose .exec() 回调完成执行?
【发布时间】:2021-10-14 02:27:58
【问题描述】:

我正在开发一个使用 Express 和 Mongoose 并使用 Jest 进行测试的应用程序。我目前有一个在本地内存中设置的 mongodb 用于测试目的。我在几个测试中遇到了一个问题,在我实际测试我需要的值之前,猫鼬查询的 .exec() 回调没有完成执行。

我正在尝试测试的功能:⠀⠀⠀⠀⠀⠀⠀⠀

exports.getLinksRulesAll = function(req, res, next) {
    linkFindAll(req, res, next, LinksRules);
}

function linkFindAll(req, res, next, ruleOrHistory) {
    // Sort by date, descending
    ruleOrHistory.find().sort({dateClicked: -1}).exec(
        function(err, links) {
            if (err) {
                res.status(400).send({message: "Error"});
                return;
            } else {
                res.status(200).json({
                    links: links
                });
            }
        }
    );
}

作为参考,LinksRules 是一个简单的猫鼬模型。

以下是我对此功能的测试:

const mockRes = () => {
    const res = {};

    res.status = jest.fn().mockReturnThis();
    res.send = jest.fn().mockReturnThis();
    res.json = jest.fn().mockReturnThis();

    return res;
};

describe("links.controller.getLinksRulesAll", () => {
    it("Provide a valid linkRule.", async () => {
        const partner = await createPartnership();
        const id = await insertLinkRule(partner._id);

        const res = mockRes();

        linksCon.getLinksRulesAll({}, res, () => {});

        expect(res.send).not.toBeCalled();
        expect(res.status).toBeCalled();
        expect(res.status).toHaveBeenCalledWith(200);
        expect(res.json).toBeCalled();
    });

    it("Provide no linkRules.", async () => {
        const res = mockRes();

        linksCon.getLinksRulesAll({}, res, () => {});

        expect(res.json).not.toBeCalled();
        expect(res.status).toBeCalled();
        expect(res.status).toHaveBeenCalledWith(400);
        expect(res.send).toBeCalled();
    });
});

createPartnership()Partnership 插入本地 mongodb,因为 LinksRule 依赖于 Partnership

这个函数(以及许多其他函数)的问题在于,模拟的res.status 对象显示没有对其进行调用。我已经尝试过console.log(res.status.mock.calls),它表明回调正在使用正确的参数执行,但 Jest 测试在完成之前完成。我尝试过使用done(),我尝试过使用猫鼬查询的thenable 方面,并且我尝试将linksCon.getLinksRulesAll() 函数调用包装成一个无用的承诺。

如何在我的 Jest 测试的 expect() 调用执行之前等待 .exec() 回调完成执行?

【问题讨论】:

    标签: javascript node.js mongodb mongoose jestjs


    【解决方案1】:

    可能通过删除回调语法并使用async/await?我不确定,但它可能会解决测试问题。

    async function linkFindAll(req, res, next, ruleOrHistory) {
        try {
            const links = await ruleOrHistory
                            .find()
                            .sort({dateClicked: -1})
                            .lean() // Get pure JSON, not a collection of Mongoose objects (faster)
                            .exec(); // return a true Promise, not a thenable
    
            res.status(200).json({links});
        } catch(err) {
            res.status(400).send({message: "Error"});
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-05
      • 1970-01-01
      • 2020-04-17
      • 1970-01-01
      • 1970-01-01
      • 2017-10-12
      • 2013-02-17
      • 1970-01-01
      相关资源
      最近更新 更多