【问题标题】:How write simple Jest mock for express-session's req.session.destroy()如何为 express-session 的 req.session.destroy() 编写简单的 Jest 模拟
【发布时间】:2019-08-05 16:58:39
【问题描述】:

我正在编写一个具有简单注销突变的 grapqhl 服务器。当我运行服务器时,一切都按预期工作,我可以通过销毁会话并清除 cookie 来注销。

这里是解析器:

export default async (root, args, context) => {

  console.log("THIS WILL LOG")
  await new Promise((res, rej) =>
    context.req.session.destroy(err => {
      if (err) {
        return rej(false);
      }
      context.res.clearCookie("qid");
      return res(true);
    })
  );
  console.log("NEVER HERE BEFORE TIMEOUT");

  // 4. Return the message
  return {
    code: "OK",
    message: "You have been logged out.",
    success: true,
    item: null
  };
};

我正在尝试编写一个简单的测试来验证 req.session.destroy 和 res.clearCookie 函数是否被实际调用。在这一点上,我并没有尝试测试是否真的清除了 cookie,因为我实际上并没有启动服务器,我只是在测试 graphql 解析器是否正确运行并且它调用了正确的函数。

这是我测试的一部分:

describe("confirmLoginResolver", () => {
  test("throws error if logged in", async () => {
    const user = await createTestUser();

    const context = makeTestContext(user.id);
    context.req.session.destroy = jest
      .fn()
      .mockImplementation(() => Promise.resolve(true));
    context.res.clearCookie = jest.fn();

    // this function is just a helper to process my graphql request.
    // it does not actually start up the express server
    const res = await graphqlTestCall(
      LOGOUT_MUTATION, // the graphql mutation stored in a var
      null, // no variables needed for mutation
      null // a way for me to pass in a userID to mock auth state,
      context // Context override, will use above context
    );
    console.log(res);
    expect(context.req.session.destroy).toHaveBeenCalled();
    // expect(res.errors.length).toBe(1);
    // expect(res.errors).toMatchSnapshot();
  });

});

同样,实际运行服务器时一切正常。问题是当我尝试运行上述测试时,我总是得到一个开玩笑的超时:

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

原因是上面解析器的 await 部分会挂起,因为它的 promise.resolve() 永远不会被执行。所以我的控制台会显示“这将记录”,但永远不会出现“超时前永远不会出现”。

我怀疑我需要编写一个更好的 jest mock 来更准确地模拟 context.req.session.destroy 内部的回调,但我想不通。

有什么想法可以在这里编写更好的模拟实现吗?

context.req.session.destroy = jest
      .fn()
      .mockImplementation(() => Promise.resolve(true));

没有剪掉它。想法?

【问题讨论】:

  • @benawad 是正确的:destroy 接受回调并需要调用它,以便您的函数中的 Promiseawait-ed 解析。

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


【解决方案1】:

试试

context.req.session.destroy = jest
      .fn()
      .mockImplementation((fn) => fn(false));

【讨论】:

  • ...或者只是context.req.session.destroy = jest.fn((f) => { f(); });
猜你喜欢
  • 1970-01-01
  • 2013-12-16
  • 1970-01-01
  • 2020-09-02
  • 1970-01-01
  • 1970-01-01
  • 2022-11-12
  • 1970-01-01
  • 2021-01-01
相关资源
最近更新 更多