Kev*_*dez 6 javascript unit-testing node.js jestjs request-promise
我有两个文件,getItemInfo.js用于进行API调用,getItemInfo.test.js哪个是相应的Jest测试文件.
在测试文件中,我正在模拟由节点模块触发的http调用request-promise.
问题出在第二个代码块上,被*********s 包围.基本上为什么在第二次单元测试中reject()错误仍然存在then()?
// getItemInfo.js
const rp = require('request-promise');
const getItemInfo = (id) => {
const root = 'https://jsonplaceholder.typicode.com/posts/';
const requestOptions = {
uri: `${root}/${id}`,
method: 'GET',
json: true
}
return rp(requestOptions)
.then((result) => {
return result;
})
.catch((err) => {
return err;
});
};
module.exports = {
getItemInfo: getItemInfo
};
Run Code Online (Sandbox Code Playgroud)
这是我的Jest单元测试文件.
// getItemInfo.test.js
const ItemService = require('./getItemInfo');
jest.mock('request-promise', () => (options) => {
const id = Number.parseInt(options.uri.substring(options.uri.lastIndexOf('/') + 1));
return new Promise((resolve, reject) => {
if (id === 12) {
return resolve({
id: id,
userId: 1,
title: '',
body: ''
});
} else {
return reject('something went wrong'); // <-- HERE IS THE REJECT
}
})
});
describe('getItemInfo', () => {
it('can pass', done => {
const TEST_ID = 12
ItemService.getItemInfo(TEST_ID).then((result) => {
console.log('result:',result);
expect(result.id).toBe(TEST_ID);
expect(result.userId).toBeDefined();
expect(result.title).toBeDefined();
expect(result.body).toBeDefined();
done();
});
});
it('can fail', (done) => {
const TEST_ID = 13;
ItemService.getItemInfo(TEST_ID)
.catch((err) => {
// *************
// This "catch" block never runs
// even if the jest.mock above Promise.rejects
// Why is that???
// *************
console.log('catch():', err);
done();
})
.then((result) => {
// this block runs instead.
// and it returns "then: something went wrong"
console.log('then():', result);
done();
});
});
});
Run Code Online (Sandbox Code Playgroud)
这是单元测试的输出.命令很简单jest.最后一行应该从catch()语句中运行,而不是then():
PASS ./getItemInfo.test.js
getItemInfo
? can pass (9ms)
? can fail (1ms)
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 0.703s, estimated 1s
Ran all test suites.
----------------|----------|----------|----------|----------|----------------|
File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |
----------------|----------|----------|----------|----------|----------------|
All files | 100 | 100 | 100 | 100 | |
getItemInfo.js | 100 | 100 | 100 | 100 | |
----------------|----------|----------|----------|----------|----------------|
console.log getItemInfo.test.js:25
result: { id: 12, userId: 1, title: '', body: '' }
console.log getItemInfo.test.js:48
then(): something went wrong
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
为什么我的jest.mock中的Promise reject()转到then()而不是catch()?
您的.catch()处理程序将被拒绝的promise转换为已解析的promise,因此只.then()调用外部处理程序.
当你这样使用时.catch():
.catch((err) => {
return err;
});
Run Code Online (Sandbox Code Playgroud)
并且不要重新抛出错误或返回被拒绝的承诺,然后拒绝被视为"已处理"并且返回的承诺将被解决,而不是被拒绝.这就像使用try/catch一样.在catch处理程序中,除非再次抛出异常,否则将处理异常.
你可以在这个简单的片段中看到:
new Promise((resolve, reject) => {
reject(new Error("reject 1"));
}).catch(err => {
// returning a normal value here (anything other than a rejected promise)
// causes the promise chain to flip to resolved
return err;
}).then(val => {
console.log("Promise is now resolved, not rejected");
}).catch(err => {
console.log("Don't get here");
});Run Code Online (Sandbox Code Playgroud)
其中任何一个都没有理由:
.then((result) => {
return result;
})
.catch((err) => {
return err;
});
Run Code Online (Sandbox Code Playgroud)
你可以删除它们.该.then()处理器就是多余的代码和.catch()处理吃排斥和把它变成一个解决的承诺.
如果你想保留.catch()处理程序,但允许拒绝向上传播,那么你需要重新抛出.
.catch((err) => {
console.log(err);
throw err; // keep promise rejected so reject will propagate upwards
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6790 次 |
| 最近记录: |