0
votes

Problem:

Would someone help me figure out how to mock fs with jest using typescript? I've tried a few things, and here is the main one:

I'm attempting to use jest to mock 'fs', but I can't seem to get jest to automock the 'fs' library in Typescript.

Here is my code:

import fs from 'fs';

jest.mock('fs');

describe('helloWorld.ts', () => {
  it('foobar', () => {

    fs.readdirSync.mockReturnValue(['foo.js', 'bar.js']);
  })
});

Typescript tells me "Property 'mockReturnValue' does not exist on type..."

cannot mock fs with jest

Environment:

Node v14.15.1
Typescript: "^4.0.3"
VS Code Typescript: 4.1.2

On a related note, I tried this with spyOn and it failed:

I tried to use this but couldn't get spyOn to work either (reference: jest typescript property mock does not exist on type )

import fs from 'fs';

describe('helloWorld.ts', () => {
  it('foobar', () => {
    jest.spyOn(fs, 'readdirSync').mockImplementation(() => {
      return ['foo.js', 'bar.js'];
    });
    console.log(fs.readdirSync('.'));
  });
});

This code fails with this typescript error TS2345:

Argument of type '() => string[]' is not assignable to parameter of type '(path: PathLike, options: BaseEncodingOptions & { withFileTypes: true; }) => Dirent[]'.
      Type 'string[]' is not assignable to type 'Dirent[]'.
        Type 'string' is not assignable to type 'Dirent'.

Related references:

1

1 Answers

1
votes

The TypeScript compiler does not know anything about fs being a mock.

You can tell it about this by using a type assertion:

(<jest.Mock>fs.readdirSync).mockReturnValue(...);

It becomes tedious work to do this everytime you use mocked functions imported from the fs module. To make the things simpler you can declare a variable whose type is a module mock, initialize it with fs and use it instead of fs in the tests:

import fs from 'fs';

jest.mock('fs');

const mockFS: jest.Mocked<typeof fs> = <jest.Mocked<typeof fs>>fs;

describe('helloWorld.ts', () => {
  it('foobar', () => {

    mockFS.readdirSync.mockReturnValue(['foo.js', 'bar.js']);
  });
});