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

2020/11/14 10:22 · javascript ·  · 0评论

我有一个叫的服务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
    };

});

我正在尝试使用茉莉花对该服务进行单元测试:

"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();       
    });
});

我阅读了有关Jasmine中的异步支持的信息,但是由于我对使用JavaScript进行单元测试相当陌生,因此无法使其正常工作。

我收到一个错误:

Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL

而且我的测试执行时间太长(大约5秒)。

有人可以帮助我提供一些可行的代码示例吗?

在函数中使用参数itdone在下面的代码中)将导致Jasmine尝试进行异步调用。

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

//this block signature will run synchronously
it("should work", function(){
  //...
});

done参数的名称没有区别,它的存在至关重要。我从过多的复制/面额中遇到了这个问题。

Jasmine异步支持文档注意到,参数(done上面命名)是一个回调,可以调用该回调以让Jasmine知道异步函数何时完成。如果您从未调用过它,Jasmine将永远不会知道您的测试已完成,并且最终会超时。

即使对于异步测试,在这种情况下也会发生超时,您可以通过增加限制超时的值来评估异步Jasmine回调来解决此错误。

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

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

    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();
            }
        });
    });
});

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

也可能是由于在初始化服务/工厂等时遗漏了注入而引起的。例如,可以通过执行以下操作将其抛出:

var service;
beforeEach(function(_TestService_) {
    service = _TestService_;
});

要解决此问题,只需在函数中插入一下即可正确检索服务:

var service;
beforeEach(inject(function(_TestService_) {
    service = _TestService_;
}));
import { fakeAsync, ComponentFixture, TestBed } from '@angular/core/testing';

使用fakeAsync

beforeEach(fakeAsync (() => {

//your code

}));



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

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

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

module.exports = function(config) {
  config.set({
    client: {
      jasmine: {
        timeoutInterval: 10000
      }
    }
  })
}

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

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

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

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

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

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

希望这对某人有帮助。

当在beforeAll函数中期望某些东西时,您也会收到此错误

describe('...', function () {

    beforeAll(function () {
        ...

        expect(element(by.css('[id="title"]')).isDisplayed()).toBe(true);
    });

    it('should successfully ...', function () {

    }
}

不要使用done,只需将函数调用留空即可。

在我的情况下,此错误是由于不当使用“ fixture.detectChanges()”引起的。似乎此方法是事件侦听器(异步),仅在检测到更改时才响应回调。如果未检测到任何更改,它将不会调用回调,从而导致超时错误。希望这可以帮助 :)

删除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} );
    });
});

正如@mastablasta所指出的,还要补充一点,如果您调用'done'参数或者更确切地说将其命名为完成,则只需在测试完成时调用回调complete()即可。

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

// this block signature will run synchronously
it("should work", function(){
  //...
});

jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;

将其保留在区块中可以解决我的问题。

it('', () => {
 jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;
});

我所做的是:添加/更新了以下代码:

framework: 'jasmine',
jasmineNodeOpts: 
{
    // Jasmine default timeout
    defaultTimeoutInterval: 60000,
    expectationResultHandler(passed, assertion) 
    {
      // do something
    },
}

Instead of

beforeEach(() => {..

use

beforeEach(fakeAsync(() => {..

It looks like the test is waiting for some callback that never comes. It's likely because the test is not executed with asynchronous behavior.

First, see if just using fakeAsync in your "it" scenario:

it('should do something', fakeAsync(() => {

You can also use flush() to wait for the microTask queue to finish or tick() to wait a specified amount of time.

If you have an argument (done) in the it function try to remove it as well it's call within the function itself:

it("should broadcast delete message notification", function(/*done -> YOU SHOULD REMOVE IT */) {

    requestNotificationChannel.deleteMessage(1, 4);
    expect(rootScope.$broadcast).toHaveBeenCalledWith("_DELETE_MESSAGE_", { id: 1, index: 4 });
    // done(); -> YOU SHOULD REMOVE IT        
});
本文地址:http://javascript.askforanswer.com/jasmineyibuhuidiaoweizaijasmine-default_timeout_intervalzhidingdechaoshineidiaoyong.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!