【问题标题】:Inject real implementation of Angular's $timeout service in a Karma/Jasmine unit test在 Karma/Jasmine 单元测试中注入 Angular 的 $timeout 服务的真实实现
【发布时间】:2016-02-02 16:26:11
【问题描述】:

我有一个小型 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 抱怨测试时间太长了,因为 mocked$timeout 服务实际上从未启动其延迟超时:

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

【问题讨论】:

  • 你必须使用 $timeout.flush() 来结束 $timeout

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


【解决方案1】:

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

it('a ctrl with $timeout inside', inject(function($timeout) {
    var myCOntroller = $controller('Controller', { $scope: $scope });

    // flush timeout(s) for all code under test.
    $timeout.flush();

    // this will throw an exception if there are any pending timeouts.
    $timeout.verifyNoPendingTasks();

    expect($scope.result).toBe("whatIexpect");
}));

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

    $timeout.flush();
});

一切都好explain here :)

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

【讨论】:

  • 谢谢,这很有帮助!虽然它实际上并没有回答我原来的问题,但您的链接显示了一个将毫秒超时传递给 flush() 函数以允许更细粒度控制的示例 - 我不知道被模拟的 $timeout 具有这种能力。这应该让我有信心测试我的功能。
猜你喜欢
  • 2017-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
相关资源
最近更新 更多