I am trying to mock a function in a third-party node module, specifically the fs.readFileSync() function, using jest. There are quite a few examples out there but I haven't found one which uses TypeScript. I have a simple, hopefully minimal, example at github. This is probably a simple issue for someone familiar with jest.
Here are a few different ways of mocking something like fs.readFileSync():
Mock the function
To mock a function use jest.spyOn() in combination with functions like mockImplementation():
import { returnNameInJsonFile } from './index';
import * as fs from 'fs';
describe('index', () => {
  it('returnNameInJsonFile', () => {
    const mock = jest.spyOn(fs, 'readFileSync');  // spy on fs.readFileSync()
    mock.mockImplementation(() => JSON.stringify({ name: 'myname' }));  // replace the implementation
    const name: string = returnNameInJsonFile('test.json');
    expect(name).toBe('myname');
    mock.mockRestore();  // restore fs.readFileSync()
  });
});
Mock the module using a factory
Pass a module factory to jest.mock():
import { returnNameInJsonFile } from './index';
jest.mock('fs', () => {
  const MOCK_FILE_INFO = { 'test.json': JSON.stringify({ name: 'myname' }) };
  return {
    readFileSync: (fpath, opts) => {
      if (fpath in MOCK_FILE_INFO) {
        return MOCK_FILE_INFO[fpath]
      }
      throw 'unexpected fpath'
    }
  }
});
describe('index', () => {
  it('returnNameInJsonFile', () => {
    const name: string = returnNameInJsonFile('test.json');
    expect(name).toBe('myname'); // 1.0.0 is installed and 2.0.0 is available
  });
});
Mock the module automatically
Create a mock for the module.
Jest will use the mock automatically unless it is a core Node module (like fs) in which case calling jest.mock() is required.
__mocks__/fs.ts:
const fs = jest.genMockFromModule('fs');
let mockFiles: object = {};
function __setMockFiles (newMockFiles: object) {
  mockFiles = newMockFiles;
}
function readFileSync(filePath: string) {
  return mockFiles[filePath] || '';
}
// If anyone knows how to avoid the type assertion feel free to edit this answer
(fs as any).__setMockFiles = __setMockFiles;
(fs as any).readFileSync = readFileSync;
module.exports = fs;
index.test.ts:
import { returnNameInJsonFile } from './index';
jest.mock('fs');  // Required since fs is a core Node module
describe('index', () => {
  const MOCK_FILE_INFO = { 'test.json': JSON.stringify({ name: 'myname' }) };
  beforeEach(() => {
    require('fs').__setMockFiles(MOCK_FILE_INFO);
  });
  it('returnNameInJsonFile', () => {
    const name: string = returnNameInJsonFile('test.json');
    expect(name).toBe('myname'); // 1.0.0 is installed and 2.0.0 is available
  });
});
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With