【问题标题】:Why can't I mock `crypto.createHash`?为什么我不能模拟`crypto.createHash`?
【发布时间】:2022-02-14 07:30:55
【问题描述】:

我正在尝试测试一个使用 Node 的 crypto.createHash 函数的函数。但是,当我尝试使用 jest.mock('crypto', () => ({ createHash: … })) 模拟它时,模拟似乎不起作用。

被测单元同时使用Hash#updateHash#digest,所以我试图将它们添加到createHash 模拟中,但是当单元运行时,createHash 返回undefined

src/hash.ts

import { createHash } from 'crypto';

export function hash(input: string | Uint8Array): Uint8Array {
  return new Uint8Array(createHash('sha512').update(input).digest().buffer);
}

src/__test__/hash.test.ts

import { createHash } from 'crypto';

import { hash } from '../hash-node.js';

const mockDigest = jest.fn();

jest.mock('crypto', () => ({
  createHash: jest.fn().mockReturnValue({
    update: jest.fn().mockReturnThis(),
    digest: mockDigest,
  }),
}));

describe('hash', () => {
  it('uses SHA512', () => {
    hash('foo');

    expect(createHash).toHaveBeenCalledWith(
      expect.stringMatching(/sha512/i),
    );
  });
});

输出

    TypeError: Cannot read properties of undefined (reading 'update')

      3 |
      4 | export function hash(input: string | Uint8Array): Uint8Array {
    > 5 |   return new Uint8Array(createHash('sha512').update(input).digest().buffer);
        |                         ^
      6 | }
      7 |

      at hash (src/hash.ts:4:25)
      at Object.<anonymous> (src/__test__/hash.test.ts:16:5)

如您所见,createHash 显然返回了 undefined,就好像 .mockReturnValue 没有被调用一样。

我做错了什么?我怎样才能让这个模块模拟工作?

【问题讨论】:

  • 它对我来说很好用。你有__mocks__ 目录吗?
  • 没有。此时,只需模块和测试。

标签: node.js typescript unit-testing jestjs


【解决方案1】:

我回过头来想明白了;这是将 Jest 配置为在测试之间重置模拟的结果。一旦我将 createHash 上的 mockReturnValue 调用移动到 beforeEach 块内,一切都开始按预期工作。

import { type Hash, createHash } from 'crypto';

import { hash } from '../hash.js';

const mockDigest = jest.fn();

jest.mock('crypto', () => ({
  createHash: jest.fn(),
}));

describe('hash', () => {
  beforeEach(() => {
    (createHash as jest.MockedFunction<typeof createHash>).mockReturnValue({
      update: jest.fn().mockReturnThis(),
      digest: mockDigest,
    } as unknown as Hash);
  });

  it('uses SHA512', () => {
    hash('foo');

    expect(createHash).toHaveBeenCalledWith(
      expect.stringMatching(/sha512/i),
    );
  });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    相关资源
    最近更新 更多