8

I try to mock the module uuid/v4 coming from npm. To do that, I have created a mock folder as suggested by jest : https://jestjs.io/docs/en/manual-mocks

My folder structure :

├──__mocks__ 
|  └──uuid
|       └──v4.ts
├──src
│   └──__tests__
│   └── ...
├──node_modules

The mock node module file v4.ts :

module.exports = jest.fn();

When I try to import uuid/v4 in my test file, jest should normally import the mock and I should be able to play with it.

Here my test file :

import uuidv4 from 'uuid/v4';

it('should create a job', () => {
    const jobId = 'fake-job-id';
    uuidv4.mockReturnValue(jobId); 
    ...
}

Unfortunately, the mock import seems not working because I can't add the mockReturnValue provided by jest and I have the following typescript error : property 'mockReturnValue' does not exist on type v4. ts(2339)

Do you have any idea how I can fix that please ? Thanks by advance.

Putxe
  • 1,054
  • 1
  • 16
  • 23

1 Answers1

12

A common way to handle a situation like this is to auto-mock the module in the test, then tell TypeScript the module is auto-mocked by using jest.Mocked like this:

jest.mock('uuid/v4');  // <= auto-mock uuid/v4

import uuidv4 from 'uuid/v4';
const mocked = uuidv4 as jest.Mocked<typeof uuidv4>;  // <= tell TypeScript it's an auto-mock

test('hi', () => {
  mocked.mockReturnValue('mocked result');  // <= use the properly typed mock
  expect(uuidv4()).toBe('mocked result');  // Success!
})

Unfortunately the typing for uuid/v4 doesn't seem to work right with this approach.

As a workaround you can use a type assertion:

jest.mock('uuid/v4');  // <= auto-mock uuid/v4

import uuidv4 from 'uuid/v4';

test('hi', () => {
  (uuidv4 as jest.Mock).mockReturnValue('mocked result');  // <= use a type assertion
  expect(uuidv4()).toBe('mocked result');  // Success!
})
Brian Adams
  • 43,011
  • 9
  • 113
  • 111
  • Thank you Brian it works perfectly ! I have noted that it works also just with : `jest.mock('uuid/v4'); const uuidv4 = require('uuid/v4'); ` and without need of type assertion. – Putxe Sep 05 '19 at 14:42
  • 1
    Awesome, good to hear! Yeah, using `jest.Mocked` is ideal since it maintains type safety, but since the typing doesn't work right in this case either the type assertion (some type safety) or `const uuidv4 = require('uuid/v4');` (`uuidv4` is type `any`) work fine as workarounds. – Brian Adams Sep 05 '19 at 15:03