javascript - 使用 Jest 测试预期会失败的 Promise
问题描述
我正在尝试使用 Jest 来测试一个返回承诺的函数。
函数 manyUrls 需要传递一个包含 JSON 数据的 URL 数组。获取这些 URL 的内容并以数组的形式返回。我正在测试传递有效 URL 字符串的情况。这会按预期抛出 TypeError,但我无法使用 Promise 为其编写测试(async/await 工作正常)
//index.js
const manyUrls = (urls) => {
return Promise.all(urls.map(url => fetch(url)))
.then(responses =>
Promise.all(responses.map(res => res.json()))
).then(texts => {
return Promise.resolve(texts)
}).catch(error => {
return Promise.reject(error)
})
}
//index.test.js
const manyUrls = require("./index")
const url = 'https://jsonplaceholder.typicode.com/todos/1'
test('Expect TypeError if a single string is passed', () => {
// expect.assertions(1);
// try {
// await manyUrls(url);
// } catch (e) {
// expect(e).toBeInstanceOf(TypeError);
// }
return manyUrls(url).catch(e =>
expect(e).toBeInstanceOf(TypeError)
)
})
我已经注释掉了使用 async/await 成功通过该测试用例的代码位(如果我将 async 添加到回调中),但我正在尝试使用 Promise 来完成这项工作。我遵循了https://jestjs.io/docs/asynchronous上的文档,但似乎无法通过该测试。有谁知道为什么?
提前致谢,
解决方案
如果你的函数返回一个 Promise,你的代码就可以正常工作 -但当return manyUrls(url)...
参数不是数组时它不会。manyUrls
urls
返回 Promise 并以 Error 拒绝的函数与抛出 Error 的函数之间存在很大差异。通过return
在您的测试中使用,您告诉 Jest 您的功能是前者,而实际上您的功能是后者。
在manyUrls
第一行中,return Promise.all(urls.map(url => fetch(url)))
尝试调用urls.maps
但在不是数组时抛出错误urls
(如在测试用例中)。在抛出错误时,不会返回任何 Promise。
您的 try/catch 实现有效,因为它捕获了manyUrls
抛出的错误。如果您希望return
实现工作,则manyUrls
必须返回一个拒绝的 Promise。
更新manyUrls
以始终返回 Promise 的最简单方法是添加async
关键字 - 就像在const manyUrls = async (urls) => {
. 通过将其设为异步函数,任何抛出的错误manyUrls
都将自动转换为返回的 Promise 的拒绝值。请参阅:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function#return_value
推荐阅读
- c# - C# 和 MongoDriver - 如何从外部集合中获取值(聚合 + 查找)?
- reactjs - React Native 不能在文本中嵌套视图
- flutter - 如何将字符串转换为列表
- hdl - 如何在 SpinalHDL 中将流连接到流
- xamarin.android - 如何将文本存储在资产目录中文本文件中的字符串变量中?
- javascript - 更改被点击的唯一按钮的颜色
- c# - 读取 txt 文件并在类中导入为 ac# 代码
- xslt - 如何编写 XSLT 脚本以将电子表格中的数据导入 HTML 文件?
- c++ - 如何将向量中对象的数据写入文件?
- php - 函数打印值但不返回