【问题标题】:Jest test times out, manual test works fine开玩笑测试超时,手动测试工作正常
【发布时间】:2022-10-21 07:18:58
【问题描述】:

我正在尝试使用 Jest 测试 nodejs 函数。我是 Jest 的初学者,所以我认为这是我构建测试的方式中的一个问题。

当手动或从应用程序中调用时,该函数可以正常工作。但是当从 Jest 测试中调用时,它要么超时,要么返回一个空对象,要么跌倒。

要测试的功能:

async function createUser(username, password){
    try{
        const user = await UserModel.create({ username, password });
        return true;
    } catch(error){
        if(error.code == 11000){
            const field = Object.keys(error.keyValue);
            const err = Error("Account with username " + field + " already exists");
            throw err;
        }
        if(error.name == 'ValidationError'){
            const err = Error("Error creating new user");
            throw err;
        }
        const err = Error("Unknown error creating new user");
        throw err;
    }
}

和我创建的 Jest 测试:

test('createUser: Non empty input should create account and return true', async () => {
    const data = await register.createUser('johnsmith1', 'smithjohn');
    expect(data).toBe(true);
});

test('createUser: Duplicate user/pass should not create user and should throw error', async () => {
    try{
        await register.createUser('johnsmith1', 'smithjohn');
    } catch(error){
        expect(error).toMatch('error');
    }
});

当运行两个测试超时:

createUser: Duplicate user/pass should not create user and should throw error

    thrown: "Exceeded timeout of 5000 ms for a test.
    Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."

      74 | });
      75 |
    > 76 | test('createUser: Duplicate user/pass should not create user and should throw error', async () => {
         | ^
      77 |     try{
      78 |         await register.createUser('johnsmith1', 'smithjohn');
      79 |     } catch(error){

      at Object.test (tests/register.test.js:76:1)

【问题讨论】:

    标签: node.js mongodb express jestjs


    【解决方案1】:

    您的 createUser 需要超过 5 秒,这是开玩笑的默认超时。

    为了增加单个测试的超时时间,作为测试函数的第三个参数。

    更多信息在这里:jset setTimeout per test

    test('createUser: Non empty input should create account and return true', async () => {
        const data = await register.createUser('johnsmith1', 'smithjohn');
        expect(data).toBe(true);
    }, 10000); // Jest will wait 10000 ms
    

    为了增加全局超时,你可以阅读这个

    configure-jest-timeout-once-for-all-tests

    【讨论】:

    • 增加超时恕我直言不是一个好主意。当一个或多个测试超时时,这意味着在大多数情况下,您没有模拟某些 API 调用,或者可能在某处错过了一些等待。单元测试不应调用外部 API 或发出网络请求。在测试中,您要测试createUser 方法而不是UserModel.create。我的建议是你应该模拟 UserModel.create 方法并返回你想要的值。然后为您捕获的所有ifelse 条件编写测试。
    【解决方案2】:

    感谢 Marek Rozmus。

    解决方案是我需要使用模拟来返回虚拟数据,而不是使用对 mongoose 的调用。

    模拟调用后,测试按预期工作。还了解了如何制定更好的测试——我们不是在测试 mongoose,只是我们的代码是否可以处理 mongoose 可能返回的内容(成功、错误、超时等)

    【讨论】:

      猜你喜欢
      • 2018-04-05
      • 2018-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-06
      • 2020-03-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多