Node.js 和 Jest:测试 promise 循环,计算函数被调用了多少次

Node.js and Jest: Testing promise loop, count how many times function has been called

我想使用 JEST 测试我的代码,但我遇到了一些问题。我想检查 restart() 函数是否被调用。

我的代码是这样工作的,它正在等待数据,如果没有数据,它会再次调用相同的函数。基本上就像一个循环。

myCode.js 文件:

module.exports = {
    getSomething: async () => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve("");
            }, 1000);
        });
    },
    doSomething: async () => {
        const data = await module.exports.getSomething();
        if (!data) {
            return module.exports.restart();
        }
        return data;
    },
    restart: async () => {
        return module.exports.doSomething();
    }
};

myCode.test.js 文件:

const myCode = require("./exampleCode")

describe("test", () => {
    test("Is it doing something more than once?", async () => {
        const restartSpy = jest.spyOn(myCode, 'restart');
        myCode.doSomething()
        expect(restartSpy).toHaveBeenCalledTimes(1);
    })
})

我的问题是 expect(restartSpy).toHaveBeenCalledTimes(1); 返回错误。

问题是 - 我做错了什么?有没有办法测试这段代码?

这里的主要问题是myCode.doSomething()之前缺少await。你所有的函数都是异步的,所以你需要等待它们完成后再检查间谍:

await myCode.doSomething();

另一个问题是它是一个无限递归循环 - 如果您不修改调用 restart 的代码,jest 将在 5000 毫秒后超时(默认情况下),例如:

doSomething: async (restartCounter = 0) => {
    const data = await module.exports.getSomething();
    if (!data && ++restartCounter < 2) {
        return module.exports.restart(restartCounter);
    }
    return data;
},
restart: async (restartCounter) => {
    return module.exports.doSomething(restartCounter);
}

实际上,我找到了解决方法。

describe("test", () => {
    test("Is it doing something more than once?", async () => {
        myCode.restart = jest.fn()
        const restartSpy = jest.spyOn(myCode, 'restart');
        await myCode.doSomething()
        expect(restartSpy).toHaveBeenCalledTimes(1);
    })
})

我正在覆盖 restart() 函数。所以现在,我可以将 await 添加到 doSomething() 函数,它将不再是无限循环。现在我可以检查是否调用了重启函数