在Karma / Jasmine单元测试中注入Angular的$ timeout服务的实际实现

时间:2016-02-02 16:26:12

标签: javascript angularjs unit-testing jasmine karma-runner

我有一个小的Angular服务,可以处理其他函数的异步速率限制,类似于this example。由于此类的主要目的是缓和异步行为,我希望能够异步测试此服务 - 我无法证明此类正在使用纯同步测试。

如果我理解正确,当加载Angular的ngMock模块时,内置的$timeout服务将替换为$timeout的模拟版本,允许测试同步运行通常是异步的。但是,在这种情况下,我想使用$timeout的实际实现而不是模拟版本。

如何将$timeout的实际实施注入单元测试?

这是我目前的测试结果(我在TypeScript中编写测试):

describe('My Tests', () => {

    let myService: MyService,
        $timeout: ng.ITimeoutService;

    beforeEach(() => {
        inject(($injector) => {
            // this gets me the mocked version of $timeout
            $timeout = $injector.get('$timeout');
        });

        myService = new MyService($timeout);

        jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
    });

    it('should pass', (done) => {
        $timeout(50)
            .then(() => {
                // this is never called
                expect(1).toBe(1);
            })
            .finally(done);
    });

});

当我运行此测试时,Karma抱怨测试也花了很长时间,因为模拟的$timeout服务实际上从未启动其延迟超时:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

1 个答案:

答案 0 :(得分:2)

你需要调用$ timeout.flush();强制释放控制器内的所有$ timeout:

ArrayList<Dotcom> dotcomlist = new ArrayList<Dotcom>();

一切都更好explain here:)

此外,你永远不应该使用真正的$ timeout,因为它真的会减慢你的测试......