Мы создаем приложение узла, основанное на экспрессе, для чтения из статического локального файла и возврата JSON в этом файле.
Вот наш json-file.js
с нашим методом маршрута:
const readFilePromise = require('fs-readfile-promise');
module.exports = {
readJsonFile: async (req, res) => {
try {
const filePath = 'somefile.json';
const file = await readFilePromise(filePath, 'utf8');
res.send(file);
} catch(e) {
res.status(500).json(e);
}
},
};
мы используем сторонний модуль, fs-readfile-promise
, который в основном превращает узел readFileSync
в обещание.
Но мы изо всех сил пытаемся смутить реализацию этой третьей стороны, чтобы иметь возможность произвести два теста: один основан на смоделированном файле чтения (обещание выполнено), а другой - на отклонении.
Вот наш тестовый файл:
const { readJsonFile } = require('../routes/json-file');
const readFilePromise = require('fs-readfile-promise');
jest.mock('fs-readfile-promise');
const resJson = jest.fn();
const resStatus = jest.fn();
const resSend = jest.fn();
const res = {
send: resSend,
status: resStatus,
json: resJson,
};
resJson.mockImplementation(() => res);
resStatus.mockImplementation(() => res);
resSend.mockImplementation(() => res);
describe('json routes', () => {
beforeEach(() => {
resStatus.mockClear();
resJson.mockClear();
resSend.mockClear();
});
describe('when there is an error reading file', () => {
beforeEach(() => {
readFilePromise.mockImplementation(() => Promise.reject('some error'));
});
it('should return given error', () => {
readJsonFile(null, res);
expect(readFilePromise).lastCalledWith('somefile.json', 'utf8'); // PASS
expect(resStatus).lastCalledWith(500); // FAIL : never called
expect(resSend).lastCalledWith({ "any": "value" }); // FAIL : never called
});
});
});
Мы пытались поместить readFilePromise.mockImplementation(() => Promise.reject('some error'));
вверху, простопосле jest.mock()
без особого успеха.
Код третьей стороны в основном выглядит примерно так:
module.exports = async function fsReadFilePromise(...args) {
return new Promise(....);
}
Как мы можем поиграть и заменить реализацию модуля для возврата либо Promise.resolve()
или Promise.reject()
в зависимости от нашей тестовой установки, чтобы наш тестовый сценарий проходил в рамках метода res.send()
или res.status()
?