javascript - 在嵌套 promise 之后使用 tick() 不会导致等待 promise 完成(Karma/Jasmine)

标签 javascript angular 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() 阻塞函数释放程序流程后设置。但是程序流并没有停止,而是在异步调用完成之前检查第二个期望。它导致规范失败。

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/

相关文章:

javascript - 通过jquery创建模态窗口

angular - Ion-slides 不更新动态数据

javascript - Angular 2 最终发布路由器单元测试

angular - 如何在 jasmine 测试中模拟事件回调触发器

angular - 测试 - 无法解析 (ClassName) 的所有参数

javascript - 如果出现平局,如何在 javascript 中返回较小的数字?

javascript - Ember : In my example why does the logic in the router continue even though the function used in it has not completed?

javascript - ng 重复不推出数据

javascript - 使用 ng update 升级到 ng9/ivy 时出错

Angular2 - 在测试时使用下划线(或任何外部库)