处理承诺异常的问题
Posted
技术标签:
【中文标题】处理承诺异常的问题【英文标题】:Issue with handling promise exceptions 【发布时间】:2021-10-07 02:02:03 【问题描述】:大家好,我正在尝试使用 javascript 解决问题陈述,该陈述具有一个简单的按钮,可以在其 onclick 中将电影添加到收藏夹。如果电影已经被添加到收藏夹中,该函数应该抛出一个Promise.reject()
。
因此,addFavourite()
有一些测试用例,并且一些测试用例失败了。你能告诉我为什么吗?我无法更改测试文件,所以我应该在我的代码中更改什么来解决错误?
这是我的addFavourite()
函数。 (注意:allMovies 是所有电影对象的列表):
function addFavourite(searchId)
var favMovie = [];
allMovies.forEach((iterator) =>
if (iterator.id == searchId)
favMovie = iterator;
);
var movieRepeated = false;
allFavourites.forEach((iterator) =>
if (iterator.id == favMovie.id)
movieRepeated = true;
);
if (movieRepeated)
return Promise.reject(new Error("Movie repeated!")).then(
resolved,
rejected
);
else
fetch("http://localhost:3000/favourites",
method: "POST",
headers:
"content-type": "application/json",
,
body: JSON.stringify(favMovie),
)
.then((response) =>
if (response.ok)
return response.json();
)
.then((addedMovie) =>
allFavourites.push(addedMovie);
displayFavs(allFavourites);
return allFavourites;
);
这些是失败的测试用例:
1.
it('adding of same movie as favourite twice shall be restricted', (done) =>
fetchMock.get('http://localhost:3000/movies', moviesTestData);
fetchMock.get('http://localhost:3000/favourites', favouritesTestData);
fetchMock.post('http://localhost:3000/favourites', moviesTestData[0]);
script.getMovies()
.then(() =>
return script.getFavourites();
)
.then(() =>
return script.addFavourite(476307);
)
.catch((err) =>
expect(err).to.not.equal(null, err);
expect(err.message).to.equal('Movie is already added to favourites');
done();
);
);
it(`addFavourites() shall hit the correct api with correct data and
return correct response`, (done) =>
fetchMock.get('http://localhost:3000/movies', moviesTestData);
fetchMock.get('http://localhost:3000/favourites', favouritesTestData);
fetchMock.post('http://localhost:3000/favourites', moviesTestData[0]);
script.getMovies()
.then(() =>
return script.getFavourites();
)
.then(() =>
return script.addFavourite(476307);
)
.then((res) =>
const lastCallArgs = fetchMock.lastCall();
expect(lastCallArgs[0]).to.equal('http://localhost:3000/favourites');
expect(lastCallArgs[1].method).to.equal('POST');
expect(lastCallArgs[1].body).to.equal(JSON.stringify(moviesTestData[0]));
favouritesTestData.push(moviesTestData[0]);
expect(res).to.deep.equal(favouritesTestData);
expect(document.getElementById('favouritesList').innerhtml)
.to.include('The Unique Lama');
done();
)
.catch((err) =>
expect(err).to.equal(null, err);
done();
);
);
这是我得到的错误:
addFavourites() shall hit the correct api with correct data and return correct response:
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
at listOnTimeout (internal/timers.js:554:17)
at processTimers (internal/timers.js:497:7)
【问题讨论】:
您正在测试== favMovie.id
,但favMovie
是一个数组并且没有.id
属性?!
".then(resolved, rejected)
" - 这闻起来像Promise
constructor antipattern!并注意它返回一个始终履行的承诺 a,因为 rejected
处理错误。
您在fetch(…).then(…);
承诺链前面缺少return
。
我错误地将 favMovie 初始化为数组 []!这是一个对象,应该是 。一旦我遍历所有电影并找到具有相同 id 的对象,它就会存储该对象的值。
另外,我想我需要先了解 Promise 是如何工作的,然后我才能了解这里发生了什么!不过非常感谢。
【参考方案1】:
您可能还需要在 then
主体中调用 done()
,因为您没有向测试运行器返回承诺。
【讨论】:
以上是关于处理承诺异常的问题的主要内容,如果未能解决你的问题,请参考以下文章