【发布时间】:2018-12-21 13:11:17
【问题描述】:
直到现在我都认为自己在 JavaScript 方面表现不错。我想为我的 HTTP 请求编写一个辅助函数。我用 Jest 测试了它。问题是catch() 部分没有被触发。让我先给你测试一下:
it("recognizes when a response's status is not okay", () => {
fetch.mockResponseOnce(JSON.stringify({ ok: false }));
expect.assertions(1);
return getRequestWithoutHeader(fullTestUrl).catch(err => {
expect(err.ok).toEqual(false);
});
});
也许测试写错了导致失败。不管怎样,这里是我写的辅助函数。我尝试了不同的实现,但都没有通过测试:
// Implementation one: with throw
export const getRequestWithoutHeader = fullUrlRoute =>
fetch(fullUrlRoute).then(response =>
response.json().then(json => {
if (!response.ok) {
throw Error(json);
}
return json;
}, error => error)
);
// Implementation two: with throw new
export const getRequestWithoutHeader = fullUrlRoute =>
fetch(fullUrlRoute).then(response =>
response.json().then(json => {
if (!response.ok) {
throw new Error(json);
}
return json;
}, error => error)
);
// Implementation three: With Promise.reject
export const getRequestWithoutHeader = fullUrlRoute =>
fetch(fullUrlRoute).then(response =>
response.json().then(json => {
if (!response.ok) {
return Promise.reject(json);
}
return json;
}, error => error)
);
// Implementation four: with new Promise
export const getRequestWithoutHeader = fullUrlRoute =>
new Promise((resolve, reject) => {
fetch(fullUrlRoute).then(response =>
response.json().then(
json => {
if (!response.ok) {
reject(json);
}
resolve(json);
},
error => reject(error)
)
);
});
这些都不起作用。其中一些将在测试中使用then 返回,但我希望能够抛出承诺。我想触发捕获。
我该如何编写这个辅助函数?
【问题讨论】:
-
您应该在
response上调用.json()之前检查ok。 (另外,最好不要嵌套这样的 Promise ——这就是 Promise-as-callback 反模式) -
@CertainPerformance 您能否提供一个代码示例?我现在尝试这样做:codepen.io/anon/pen/Zjbbpb 仍然失败。
-
你不想要嵌套的
.then(json => json);(如果你想用它做点什么,把它放在一个外部的.then中)。你也不想catchgetRequestWithoutHeader里面的错误,否则它会返回一个resolvedPromise(不会被你的测试捕获) -
@CertainPerformance 嗯,我仍然无法让它工作。我现在是这样实现的:codepen.io/anon/pen/Zjbbpb 对不起,我学得太难了。非常感谢您的耐心和帮助!
-
是的,现在看起来不错!不幸的是,我没有使用 Jest 的经验,所以如果该代码不起作用,我不知道修复它的下一步是什么
标签: javascript ecmascript-6 fetch jestjs es6-promise