我需要在 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() 阻塞函数释放程序流程后设置。但是程序流并没有停止,而是在异步调用完成之前检查第二个期望。它导致规范失败。
Angular CLI 6.2.6、Karma 3.1.1、Jasmine 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
,但这似乎是一个非常安全的赌注。他们没有异常(exception),允许针对 fetch
URL 的 data:
被区别对待,这也不足为奇。即使它实际上没有触发网络事件,它仍然使用 Promise 异步运行。
其次,我不确定你的真实代码是什么样的,但是你编写的测试基本上是检查基本的浏览器功能(或你的 polyfill?)是否正常工作。如果您实际上只需要从一些静态数据中创建一个 Blob,则有更简单的方法可以在不调用 fetch
的情况下完成此操作。
关于javascript - 在嵌套 promise 之后使用 tick() 不会导致等待 promise 完成(Karma/Jasmine),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53503585/