【问题标题】:Jest returning false positives for Firebase functions?开玩笑返回 Firebase 函数的误报?
【发布时间】:2020-12-02 18:40:11
【问题描述】:

不得不为 Firebase 函数编写一些 Jest 测试,我遇到了一些麻烦。这是我正在尝试做的一个基本示例:

databaseUtils.js

function funcOne() {
  return Promise.resolve();
}

function funcTwo() {
  return Promise.resolve();
}

index.js

exports.myTest = functions.https.onRequest(async (req, res) => {
  try {
    await databaseUtils.funcOne();
    await databaseUtils.funcTwo();
    return res.status(200);
  } catch (error) {
    console.log(error);
    return res.status(403);
  }
});

index.test.js

describe('myTest', () => {
    it('test 1', async () => {
        const req = {}
        const res = {
            status: jest.fn()
        };
        await functions.myTest(req, res);
        expect(res.status).toHaveBeenCalledWith(200)
    });

    it('test 2', async () => {
        const req = {}
        const res = {
            status: code => {
                expect(code).toBe(403);
            }
        };
        await functions.myTest(req, res);
    });

    it('test 3', (done) => {
        const req = {}
        const res = {
            status: code => {
                expect(code).toBe(403);
                done();
            }
        };
        functions.myTest(req, res);
    });
})

当我运行测试时,测试 1 失败,而测试 2 和 3 通过,但值错误:

JestAssertionError: expect(received).toBe(expected) // Object.is equality
    
    Expected: 403
    Received: 200
      matcherResult: {
        actual: 200,
        expected: 403,
        message: [Function],
        name: 'toBe',
        pass: false
      }

一直在兜圈子试图让它正常工作,但我不知道,我做错了什么?

一旦我弄清楚了这一点,我就会模拟 funcOne / funcTwo 以返回一个被拒绝的承诺,这样我就可以获得正确的状态代码。

【问题讨论】:

    标签: javascript firebase jestjs


    【解决方案1】:

    onRequest 具有承诺意识,并期望返回它所做的整个工作的承诺。 onRequest 回调内部有一个悬空的承诺是一种反模式。

    应该是:

    return auth.decodeToken(req)...
    

    async 内部存在带有 thencatch 的原始 Promise 会导致问题,因为 async..await 是一种糖语法,可以避免一些常见的 Promise 问题。如果写成这样,则可以避免上述问题以及嵌套承诺:

    try {
      const decodedToken = await auth.decodeToken(req);
      ...
    } catch (err) {
      ...
    }
    

    【讨论】:

    • 感谢您发现并清理它!我重写了一个虚拟测试并使用 try/catch 更新了原始帖子,但我仍然得到相同的结果。
    • 这是真正的肯定,因为您没有为函数失败做任何事情。负责失败的模拟单元,因为 databaseUtils 函数用作方法,它们可以在没有 jest.mock 的情况下被模拟,例如 jest.spyOn(databaseUtils, 'funcOne').mockRejectedValue('foo'); ... expect(res.status).toHaveBeenCalledWith(403)
    猜你喜欢
    • 2022-10-24
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多