我有功能想要进行单元测试,例如,它包含:
function foo (file, option) {
return new Promise((resolve, reject) => fs.readFile(file, option, (err, content) => {
if (err) return reject(new Error(`Failed to read the file: (${file})`));
else {
(...some operations, and that is the point for me to test it...)
return resolve(...some result...);
}
}));
}
就在测试文件的开头,我有:
jest.mock('fs', () => ({
readFile : jest.fn(),
}));
const fs = require('fs');
测试逻辑类似于:
test('Should get context as string from the template file', async () => {
const mockContent = '<a>Hello World</a>';
fs.readFile.mockReturnValue(mockContent);
const result = (await foo('test', 'utf8')).then(() => 123);
//
expect(result).toEqual(123);
});
但是,当我尝试运行测试时,它会显示:
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.`
我知道这是一个问题,因为Jest网站未能解决这个问题;但他们的建议不是我实际上的......我认识到我的问题是由于fs.readFile(...)
被返回undefined
的模拟函数所取代,因此new Promise
永远不会被拒绝/解决了(我说错了吗?!)。
我的问题是如何像这种情况一样进行单元测试?我真的不想发起一个I / O事件,比如在oder中使用一个空文件来使它工作......有什么想法吗?!谢谢!
///更新: 我认为一个非常明确的问题是我们如何模拟回调函数接收的数据。在我的例子中,它看起来像我测试它,但在我的真实代码中,我真正想要测试的是回调函数的逻辑。
答案 0 :(得分:3)
问题在于你模仿js.readFile
的方式。 mockReturnValue
只是创建一个返回某个东西的函数,但是你希望它调用它的参数,所以你需要使用mockImplementation
自己定义模拟函数
jest.fn().mockImplementation((file, option, cb) => cb(null, mockContent))
或
jest.fn().mockImplementation((file, option, cb) => cb('Some Error', null))