[英]Mock imported function with jest in an await context
我們正在基於express創建一個節點應用程序,以從靜態本地文件中讀取並返回文件中的JSON。
這是我們的json-file.js
和我們的route方法:
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()
方法中通過?
最后兩個斷言永遠不會通過,因為測試不會等待以下承諾: const file = await readFilePromise(filePath, 'utf8');
在這種情況下解決或拒絕,因此從不調用res.send
或res.status
。
要修復它, readJsonFile
是async
,您應該在測試中await
它:
it('should return given error', async () => {
await readJsonFile(null, res);
...
})
我們如何模擬和替換模塊的實現以根據我們的測試設置返回Promise.resolve()或Promise.reject(),以使測試用例在res.send()或res.status()方法中通過
確切的做法是:
readFilePromise.mockImplementation(() => Promise.reject('some error'));
要么
readFilePromise.mockImplementation(() => Promise.resolve('SomeFileContent!'));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.