Javascript Jest:在手动模拟上恢复原始模块实现
我有一个非常常见的测试用例,我不确定什么是最好的方法 上下文 我想测试一个依赖于userland依赖关系的模块。userland依赖项(Javascript Jest:在手动模拟上恢复原始模块实现,javascript,unit-testing,jestjs,Javascript,Unit Testing,Jestjs,我有一个非常常见的测试用例,我不确定什么是最好的方法 上下文 我想测试一个依赖于userland依赖关系的模块。userland依赖项(neat csv)导出一个返回承诺的函数 目标 我想模拟neat csv的行为,这样它就可以在一次测试中拒绝一个错误。然后我要恢复原始模块实现。 抱歉,我不能在这里使用jest.spyOn,因为模块只导出一个函数 因此,我认为使用手动模拟是合适的,而且是有效的。但是,我不知道如何通过手动模拟恢复原始实现 简化示例 为了简单起见,这里是我尝试测试的模块的精简版本:
neat csv
)导出一个返回承诺的函数
目标
我想模拟neat csv
的行为,这样它就可以在一次测试中拒绝一个错误。然后我要恢复原始模块实现。
抱歉,我不能在这里使用jest.spyOn
,因为模块只导出一个函数
因此,我认为使用手动模拟是合适的,而且是有效的。但是,我不知道如何通过手动模拟恢复原始实现
简化示例
为了简单起见,这里是我尝试测试的模块的精简版本:
'use strict';
const neatCsv = require('neat-csv');
async function convertCsvToJson(apiResponse) {
try {
const result = await neatCsv(apiResponse.body, {
separator: ';'
});
return result;
} catch (parseError) {
throw parseError;
}
}
module.exports = {
convertCsvToJson
};
下面是第二次测试失败的测试尝试(非模拟版本):
我想知道jest是设计来做这些事情的,还是我走错了路,应该改为jest
处理这个问题的惯用方法是什么?是的,Jest就是用来做这些事情的
您正在寻找的API方法是。它提供了一种模拟模块的方法,而无需使用jest.mock进行隐式提升,从而允许您在测试范围内进行模拟
下面是一个测试代码的工作示例,显示了以下内容:
const csv = 'type;part\nunicorn;horn\nrainbow;pink';
const apiResponse = {
body: csv
};
const rejectionOf = promise =>
promise.then(value => {
throw value;
}, reason => reason);
test('mocked version', async () => {
jest.doMock('neat-csv', () => jest.fn().mockRejectedValueOnce(new Error('Error while parsing')));
const neatCsv = require('neat-csv');
const { convertCsvToJson } = require('./module-under-test.js');
const e = await rejectionOf(convertCsvToJson(apiResponse));
expect(neatCsv).toHaveBeenCalledTimes(1);
expect(e.message).toEqual('Error while parsing');
jest.restoreAllMocks();
});
test('non mocked version', async () => {
const { convertCsvToJson } = require('./module-under-test.js');
const result = await convertCsvToJson(apiResponse);
expect(JSON.stringify(result)).toEqual('[{"type":"unicorn","part":"horn"},{"type":"rainbow","part":"pink"}]');
});
我刚刚有机会尝试一下,但由于某些原因,这不起作用。在我的项目中我根本不用巴贝尔。doMock方法是否只有在项目中使用babel jest时才有效?否,
doMock
是jest API的一部分,它与babel无关。你的错误是什么?什么是“这行不通”的确切意思是什么?实际上,我已经在我的本地机器上设置了一个测试的工作版本,所以我相信我的答案中的代码可以工作。对我来说是这样的。我会进一步挖掘这一点,可能是我这边的一个错误。似乎该模块根本没有使用mock,而是在测试级范围使用doMock时使用了原始的模块实现。好吧,我知道我做错了什么,我仍然在根级别范围导入convertCsvToJson,所以它不知道整洁的csv模块可以被模拟。在模拟后移动它可以修复问题。非常感谢你的帮助!
const csv = 'type;part\nunicorn;horn\nrainbow;pink';
const apiResponse = {
body: csv
};
const rejectionOf = promise =>
promise.then(value => {
throw value;
}, reason => reason);
test('mocked version', async () => {
jest.doMock('neat-csv', () => jest.fn().mockRejectedValueOnce(new Error('Error while parsing')));
const neatCsv = require('neat-csv');
const { convertCsvToJson } = require('./module-under-test.js');
const e = await rejectionOf(convertCsvToJson(apiResponse));
expect(neatCsv).toHaveBeenCalledTimes(1);
expect(e.message).toEqual('Error while parsing');
jest.restoreAllMocks();
});
test('non mocked version', async () => {
const { convertCsvToJson } = require('./module-under-test.js');
const result = await convertCsvToJson(apiResponse);
expect(JSON.stringify(result)).toEqual('[{"type":"unicorn","part":"horn"},{"type":"rainbow","part":"pink"}]');
});