I'm trying to test a function which makes use of Node's crypto.createHash
function. However, when I try to mock it using jest.mock('crypto', () => ({ createHash: … }))
, the mock doesn't seem to work.
The unit under test uses both Hash#update
and Hash#digest
, so I'm trying to add those to the createHash
mock, but when the unit runs, 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),
);
});
});
Output
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)
As you can see, createHash
is clearly returning undefined
, as though .mockReturnValue
hadn't been called.
What am I doing wrong? How can I get this module mock to work?
CodePudding user response:
I came back to this and was able to figure it out; it's a result of configuring Jest to reset mocks between tests. Once I moved the mockReturnValue
call on createHash
to inside a beforeEach
block, it all started working as expected.
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: jest.fn(),
} as unknown as Hash);
});
it('uses SHA512', () => {
hash('foo');
expect(createHash).toHaveBeenCalledWith(
expect.stringMatching(/sha512/i),
);
});
});