[英]Mock imported function with jest in an await context
We are creating a node app, based on express, to read from a static local file and return the JSON within the file. 我们正在基于express创建一个节点应用程序,以从静态本地文件中读取并返回文件中的JSON。
Here is our json-file.js
with our route method: 这是我们的
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);
}
},
};
we use a third party module, fs-readfile-promise
which basically turns node readFileSync
into a promise. 我们使用第三方模块
fs-readfile-promise
,该模块基本上将节点readFileSync
变成了承诺。
But we struggle to mock implementation of this third party, to be able to produce two tests: one based on simulated read file (promise resolved) and one based on rejection. 但是我们很难模拟这个第三方的实现,以便能够产生两个测试:一个基于模拟读取文件(已解决承诺),另一个基于拒绝。
Here is our test file: 这是我们的测试文件:
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
});
});
});
We tried to place readFilePromise.mockImplementation(() => Promise.reject('some error'));
我们试图放置
readFilePromise.mockImplementation(() => Promise.reject('some error'));
at the top, just after the jest.mock()
without more success. 在顶部,
jest.mock()
之后,没有更多的成功。
The third party code is basically something like: 第三方代码基本上是这样的:
module.exports = async function fsReadFilePromise(...args) {
return new Promise(....);
}
How can we mock and replace implementation of the module to return either a Promise.resolve()
or Promise.reject()
depending on our test setup to make our test case pass within res.send()
or res.status()
method? 我们如何模拟和替换模块的实现,以根据我们的测试设置返回
Promise.resolve()
或Promise.reject()
,以使测试用例在res.send()
或res.status()
方法中通过?
The last 2 assertions never pass because the test doesn't wait for the promise in: const file = await readFilePromise(filePath, 'utf8');
最后两个断言永远不会通过,因为测试不会等待以下承诺:
const file = await readFilePromise(filePath, 'utf8');
to resolve or reject in this case, therefore res.send
or res.status
never get called. 在这种情况下解决或拒绝,因此从不调用
res.send
或res.status
。
To fix it, readJsonFile
is async
, you should await
it in the test: 要修复它,
readJsonFile
是async
,您应该在测试中await
它:
it('should return given error', async () => {
await readJsonFile(null, res);
...
})
How can we mock and replace implementation of the module to return either a Promise.resolve() or Promise.reject() depending on our test setup to make our test case pass within res.send() or res.status() method
我们如何模拟和替换模块的实现以根据我们的测试设置返回Promise.resolve()或Promise.reject(),以使测试用例在res.send()或res.status()方法中通过
Exactly how you're doing it: 确切的做法是:
readFilePromise.mockImplementation(() => Promise.reject('some error'));
or 要么
readFilePromise.mockImplementation(() => Promise.resolve('SomeFileContent!'));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.