在Karma

时间:2017-08-17 12:19:39

标签: javascript unit-testing ecmascript-6 promise karma-jasmine

我有一个不寻常的问题,我找不到任何解决方案,而且我已经尝试了很长一段时间。我创建了一个名为delay的函数,它基本上创建了一个新的Promise,它在给定的时间后自行解析。此功能的目的是能够导致承诺链的延迟。看起来有点像这样:

const delay = ms => new Promise((resolve, reject) => {
    setTimeout(resolve, ms);
});

let test = '';

const func = () => {
    delay(1000).then(() => {
        test = 'kek';
    });
};

describe('unit tests', () => {
    it('test function func', () => {
        // Act
        func();
        // Assert
        expect(test).toEqual('kek');
    });
});

问题在于测试,我在此示例中提供的单元测试将失败,因为它仅在1000 ms延迟之后变量测试设置为kek。

我尝试过常用的解决方案,例如在单元测试中使用setTimeout,并且在断言之前尝试使用jasmine.clock()。tick(1001),但我无法使其工作。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我实际上建议这样做(在lolex,定时器库),现在我确信,由于这个原因,不可能覆盖调度程序,这是一件好事。这是因为它可以改变调用的顺序,这可能是非常有问题的。

Promise始终异步解析,您必须使您的测试异步并且返回承诺。

以下是您使用异步函数编写该测试的方法:

describe('unit tests', () => {
    it('test function func', async () => {
        // Act
        let promise = func(); // wait for it to be ready
        clock.tick(1001); 
        await promise; // wait for the promise to complete.
        // Assert
        expect(test).toEqual('kek');
    });
});

这样你就不会等待1000毫秒,但测试仍然有效。

答案 1 :(得分:1)

这对我有用

import {fakeAsync, tick } from '@angular/core/testing';

describe('When ngOnInit is invoked', () => {
    it('should wait and redirect to next page', fakeAsync( () => {
        component.ngOnInit(); // contains delay inside
        tick(2000); // time to wait
        expect(routerService.navigate).toHaveBeenCalledWith('nextStep');
    }));
});