为什么我不能模拟 `crypto.createHash`?
Why can't I mock `crypto.createHash`?
我正在尝试测试一个使用 Node 的 crypto.createHash
函数的函数。但是,当我尝试使用 jest.mock('crypto', () => ({ createHash: … }))
模拟它时,模拟似乎不起作用。
被测单元同时使用 Hash#update
和 Hash#digest
,所以我试图将它们添加到 createHash
模拟中,但是当单元运行时,createHash
returns 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
没有被调用一样。
我做错了什么?我怎样才能让这个模块 mock 工作?
我回到这个问题上并弄明白了;这是配置 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),
);
});
});
我正在尝试测试一个使用 Node 的 crypto.createHash
函数的函数。但是,当我尝试使用 jest.mock('crypto', () => ({ createHash: … }))
模拟它时,模拟似乎不起作用。
被测单元同时使用 Hash#update
和 Hash#digest
,所以我试图将它们添加到 createHash
模拟中,但是当单元运行时,createHash
returns 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
没有被调用一样。
我做错了什么?我怎样才能让这个模块 mock 工作?
我回到这个问题上并弄明白了;这是配置 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),
);
});
});