jasmine:在jasmine.DEFAULT_TIMEOUT_INTERVAL指定的超时时间内未调用异步回调

Mdb*_*Mdb 128 debugging unit-testing asynchronous jasmine angularjs

我有一个名为的角度服务requestNotificationChannel:

app.factory("requestNotificationChannel", function($rootScope) {

    var _DELETE_MESSAGE_ = "_DELETE_MESSAGE_";

    function deleteMessage(id, index) {
        $rootScope.$broadcast(_DELETE_MESSAGE_, { id: id, index: index });
    };

    return {
       deleteMessage: deleteMessage
    };

});
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用jasmine对此服务进行单元测试:

"use strict";

describe("Request Notification Channel", function() {
    var requestNotificationChannel, rootScope, scope;

    beforeEach(function(_requestNotificationChannel_) {
        module("messageAppModule");

        inject(function($injector, _requestNotificationChannel_) {
            rootScope = $injector.get("$rootScope");
            scope = rootScope.$new();
            requestNotificationChannel = _requestNotificationChannel_;
        })

        spyOn(rootScope, '$broadcast');
    });


    it("should broadcast delete message notification", function(done) {

        requestNotificationChannel.deleteMessage(1, 4);
        expect(rootScope.$broadcast).toHaveBeenCalledWith("_DELETE_MESSAGE_", { id: 1, index: 4 });
        done();       
    });
});
Run Code Online (Sandbox Code Playgroud)

我读到了Jasmine中的异步支持,但由于我对使用javascript的单元测试不熟悉,因此无法使其正常工作.

我收到一个错误:

Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL
Run Code Online (Sandbox Code Playgroud)

我的测试执行时间太长(大约5s).

有人可以通过一些解释帮我提供我的代码的工作示例吗?

mas*_*sta 214

在函数中有一个参数it(done在下面的代码中)将导致Jasimne尝试异步调用.

//this block signature will trigger async behavior.
it("should work", function(done){
  //...
});

//this block signature will run synchronously
it("should work", function(){
  //...
});
Run Code Online (Sandbox Code Playgroud)

done参数的命名并没有什么区别,它的存在才是最重要的.我从太多的副本/面食中遇到了这个问题.

Jasmin Asynchronous Support文档指出,参数(done如上所述)是一个回调函数,可以调用它让Jasmine知道异步函数何时完成.如果你从不打电话,Jasmine永远不会知道你的测试已经完成并最终会超时.

  • 请注意将来遇到这个问题的随机Google员工:如果你使用的是Protractor并遇到这个问题,那么这个答案并不是你想要的 - Protractor自己调用回调. (28认同)
  • 对于描述中的args也是如此(在有角度的情况下,你需要在描述中调用注入来做到这一点) (3认同)
  • @Vincent 如果发生此错误,Protractor 用户会遇到什么问题? (2认同)

gsa*_*edo 49

作为解决方法,您可以增加限制超时以评估异步Jasmine回调

describe('Helper', function () {
    var originalTimeout;

    beforeEach(function() {
        originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
        jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;
    });

    afterEach(function() {
      jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
    });

    it('Template advance', function(doneFn) {
        $.ajax({
            url: 'public/your-end-point.mock.json',
            dataType: 'json',
            success: function (data, response) {
                // Here your expected using data
                expect(1).toBe(1)
                doneFn();
            },
            error: function (data, response) {
                // Here your expected using data
                expect(1).toBe(1)
                doneFn();
            }
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

资料来源:http://jasmine.github.io/2.0/introduction.html#section-42


Kat*_*a24 20

初始化服务/工厂或其他任何东西时,都可以通过省略注入来引起此错误.例如,它可以通过执行以下操作抛出:

var service;
beforeEach(function(_TestService_) {
    service = _TestService_;
});
Run Code Online (Sandbox Code Playgroud)

要修复它,只需使用inject包装函数以正确检索服务:

var service;
beforeEach(inject(function(_TestService_) {
    service = _TestService_;
}));
Run Code Online (Sandbox Code Playgroud)


Lij*_*ijo 9

import { fakeAsync, ComponentFixture, TestBed } from '@angular/core/testing';
Run Code Online (Sandbox Code Playgroud)

使用fakeAsync

beforeEach(fakeAsync (() => {

//your code

}));



describe('Intilalize', () => {
        it('should have a defined component', fakeAsync(() => {
            createComponent();
            expect(_AddComponent.ngOnInit).toBeDefined();
        }));
    });
Run Code Online (Sandbox Code Playgroud)


小智 7

您可以使用karma-jasmine插件全局设置默认超时间隔。

在 karma.conf.js 中添加此配置

module.exports = function(config) {
  config.set({
    client: {
      jasmine: {
        timeoutInterval: 10000
      }
    }
  })
}
Run Code Online (Sandbox Code Playgroud)


Eri*_*yke 5

在一直有效的测试中,这个错误对我来说是出乎意料的。在发现Macbook运行缓慢之前,我找不到任何有帮助的建议。我注意到CPU与另一个进程挂住了,我杀死了该进程。Jasmine异步错误消失了,我的测试再次正常。

不要问我为什么,我不知道。但是在我的情况下,似乎缺少系统资源。

  • 可能是在CPU空闲时,任务在默认超时之前完成。当CPU繁忙时,您正在测试的任务花费了太长时间才能完成。 (4认同)

del*_*ttg 5

这更多的是观察,而不是答案,但它可能会对像我一样沮丧的其他人有所帮助。

我一直从套件中的两个测试中得到此错误。我以为我只是用我的重构破坏了测试,所以在撤消更改不起作用之后,我又恢复到了早期的代码,两次(返回两次修订)都认为它可以消除错误。这样做并没有改变。昨天整天和今天早上的一部分时间,我都追不着尾巴,但没有解决问题。

我很沮丧,今天早上把代码签到了笔记本电脑上。运行了整个测试套件(约180个测试),没有错误。因此,错误永远不会出现在代码或测试中。回到我的开发箱并重新启动它,以清除内存中可能引起问题的所有内容。没有变化,在相同的两个测试中出现相同的错误。因此,我从计算机中删除了该目录,然后将其检出。瞧!没有错误。

不知道是什么原因引起的,或者如何修复它,但是删除工作目录并将其检出并修复了它是什么。

希望这对某人有帮助。


Pau*_*tte 2

scope删除引用和函数参数后起作用:

"use strict";

describe("Request Notification Channel", function() {
    var requestNotificationChannel, rootScope;

    beforeEach(function() {
        module("messageAppModule");

        inject(function($injector, _requestNotificationChannel_) {
            rootScope = $injector.get("$rootScope");
            requestNotificationChannel = _requestNotificationChannel_;
        })
        spyOn(rootScope, "$broadcast");
    });


    it("should broadcast delete message notification with provided params", function() {
        requestNotificationChannel.deleteMessage(1, 4);
        expect(rootScope.$broadcast).toHaveBeenCalledWith("_DELETE_MESSAGE_", { id: 1, index: 4} );
    });
});
Run Code Online (Sandbox Code Playgroud)