【发布时间】: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)" - 这闻起来像Promiseconstructor antipattern!并注意它返回一个始终履行的承诺 a,因为rejected处理错误。 -
您在
fetch(…).then(…);承诺链前面缺少return。 -
我错误地将 favMovie 初始化为数组 []!这是一个对象,应该是 {}。一旦我遍历所有电影并找到具有相同 id 的对象,它就会存储该对象的值。
-
另外,我想我需要先了解 Promise 是如何工作的,然后我才能了解这里发生了什么!不过非常感谢。
标签: javascript asynchronous async-await promise json-server