Below are a variety of ways to mock something similar to fs.readFileSync()
:
Mock the function
To mock a function, utilize jest.spyOn()
in conjunction with methods like mockImplementation()
:
import { returnNameInJsonFile } from './index';
import * as fs from 'fs';
describe('index', () => {
it('returnNameInJsonFile', () => {
const mock = jest.spyOn(fs, 'readFileSync');
mock.mockImplementation(() => JSON.stringify({ name: 'myname' }));
const name: string = returnNameInJsonFile('test.json');
expect(name).toBe('myname');
mock.mockRestore();
});
});
Mock the module using a factory
Supply 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');
});
});
Mock the module automatically
Create a mock for the module.
Jest
will automatically use the mock unless it is a core Node module (like fs
), in which case calling jest.mock()
is necessary.
__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');
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');
});
});