我有一个非常普通的测试用例,我不确定那里最好的方法是什么。
我想测试依赖于用户区依赖性的模块。用户名依赖项(neat-csv
)导出单个函数,该函数返回Promise 。
我想模拟neat-csv
的行为,以便它拒绝一次测试的错误。然后,我想还原原始的模块实现。
AFAIK,我无法在此处使用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
};
这是测试的第二次测试(非模拟版本)失败的尝试:
'use strict';
let neatCsv = require('neat-csv');
let { convertCsvToJson } = require('./module-under-test.js');
jest.mock('neat-csv', () =>
jest.fn().mockRejectedValueOnce(new Error('Error while parsing'))
);
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 () => {
const e = await rejectionOf(convertCsvToJson(apiResponse));
expect(neatCsv).toHaveBeenCalledTimes(1);
expect(e.message).toEqual('Error while parsing');
});
test('non mocked version', async () => {
jest.resetModules();
neatCsv = require('neat-csv');
({ convertCsvToJson } = require('./module-under-test.js'));
const result = await convertCsvToJson(apiResponse);
expect(JSON.stringify(result)).toEqual(
'[{"type":"unicorn","part":"horn"},{"type":"rainbow","part":"pink"}]'
);
});
我想知道开玩笑是设计用来做这种事情还是我走错了路,应该注入整洁的csv吗?
处理此问题的惯用方式是什么?
答案 0 :(得分:0)
是的,Jest 被设计用来做这种事情。
您要查找的API方法是jest.doMock。它提供了一种模拟模块的方式,而不会发生 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"}]');
});