javascript - 在嵌套承诺之后使用 tick() 不会导致等待承诺完成(Karma/Jasmine)
问题描述
我需要在 Angular 中创建一个测试规范,检查 base64 字符串是否转换为 Blob 对象。转换过程涉及嵌套的 Promise:
fetch(testImage1).then(res => res.blob()).then(blob => {});
我使用这个规范测试这个过程:
it( 'should update an image fakeAsync', fakeAsync( () => {
fixture.detectChanges();
let imgBlob = null;
// testImage1 = 'data:image/gif;base64,R0lGODlhPQBEAPeoAJosM//AwO/AwHVYZ/z5......'
fetch(testImage1).then(res => res.blob()).then(blob => {
imgBlob = blob;
expect(imgBlob).toBeTruthy(); //OK
});
tick();
expect(imgBlob).toBeTruthy(); //test fails
} ));
如代码所示,spec 在 fakeAsync 块中运行,并且在异步代码调用之后调用 tick() 方法。imgBlob 应该在 tick() 阻塞函数释放程序流之后设置。但是程序流程并没有停止,而是在异步调用完成之前检查第二个期望。它导致规范失败。
角 CLI 6.2.6、业力 3.1.1、茉莉花 2.8.0
作为一种解决方法,这有效:
let promise = new Promise((resolve, reject) => {
fetch(testImage1).then(res => res.blob()).then(blob => {
resolve(blob);
});
});
imgBlob = await promise;
解决方案
两件事情:
首先,@dmcgrandle 是正确的,它fakeAsync
依赖于猴子修补异步内置方法(或者更确切地说,它依赖于 Zone.js 修补它们),并且它明确不支持网络请求。至少,所有文档都说你不能使用 XHR,虽然我很惊讶地发现它没有明确说你不能使用fetch
任何一个,但这似乎是一个非常安全的选择。fetch
他们没有例外处理允许对data:
URL 进行不同处理的例外也不足为奇。即使它实际上并没有触发网络活动,它仍然使用 Promises 异步运行。
其次,我不确定您的真实代码是什么样的,但是您编写的测试基本上是检查基本浏览器功能(或您的 polyfill?)是否正常工作。如果您实际上只需要从一些静态数据中创建 Blob,则可以使用更简单的方法来执行此操作,而无需调用fetch
.
推荐阅读
- javascript - 在 JS 中循环遍历数组并在引导程序中为 HTML 提要生成帖子?
- vb.net - 在 Windows 资源管理器中,“日期”和“获取日期”给出实际拍摄照片或视频的日期。如何在 vb.net 中轻松访问它?
- php - Laravel 油门不起作用
- java - Spring:@Value 与其他类中的 lombok
- google-apps-script - Google 幻灯片中的自定义菜单
- node.js - Mocha 测试并需要缓存问题
- html - Doxygen 包含 css 到 htmlinclude 文件
- java - 通过 JAVA 运行 GDB LINUX 命令
- java - 地图
给空 - html - 如何阻止 Windows 10 Mail 从每个图像的右侧剪切 1px?