jasmine : jasmine이 지정한 시간 초과 내에 비동기 콜백이 호출되지 않았습니다 .DEFAULT_TIMEOUT_INTERVAL


141

나는라는 각도 서비스를 가지고 있습니다 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
    };

});

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

Jasmine의 비동기 지원에 대해 읽었지만 자바 스크립트로 단위 테스트를 처음 접했을 때 작동하지 못했습니다.

오류가 발생했습니다 :

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

내 테스트를 실행하는 데 시간이 너무 오래 걸립니다 (약 5 초).

누군가 내 코드의 실제 예제를 설명하는 데 도움을 줄 수 있습니까?


1
처리 이벤트는 일반적으로 다이제스트주기에서 수행됩니다. Jasmine의 비동기 테스트 패턴을 사용하는 대신 scope. $ apply ()를 테스트에 추가해보십시오
Eitan Peer

이 작동하지 않습니다. scope. $ apply ();를 추가했습니다. requestNotificationChannel.deleteMessage (1, 4)를 호출 한 직후에도 같은 오류가 발생합니다.
Mdb

비동기 테스트가 Jest예상 보다 실행 시간이 오래 걸리면 동일한 오류가 발생 합니다. 디버깅하고 변수를 검사하는 데 시간이 걸리는 경우가 매우 흔합니다.
Dan Dascalescu

대신 타임 아웃을 줄이십시오. timeout = 5000을 사용하는 동안이 오류가 발생했습니다. 2000으로 바꾸고 나에게 도움이되었습니다!
마리나 리아 즈

1
내 신발에 누군가를 돕기 위해 여기에 남겨주세요. 도커 컨테이너 내부에서 테스트를 실행하는 동안이 오류가 발생했습니다. 테스트는 문제없이 통과되지만 때로는 실패합니다. 나는 그것이 일종의 경쟁 조건이라고 생각했지만 그 이유를 알 수 없었습니다. afterEach데이터베이스를 지우는 단계 가 있음을 깨달았습니다 ( deleteMany메서드 사용). 추가 jest.setTimeout(30000);beforeAll방법은 나를 위해이 문제를 해결 한 것 같다 - 데이터베이스 삭제 (조건 내부) 네트워크 호출이기 때문에 나는 가끔 3 초와 던지는 것보다 많은 시간이 소요되었다 같은데요.
nkhil

답변:


231

it함수에 인수가 있으면 ( done아래 코드에서) 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은 테스트가 완료되었음을 알지 못하고 결국 시간 초과됩니다.


3
설명의 인수에 대해서도 마찬가지입니다 (각도에서는 설명을 위해 inject를 호출해야 함)
Narretz

@MartinBliss 그것은 문서화되어 있습니다. 나는 방금 문서를 참조하기위한 편집을 제안했습니다 : stackoverflow.com/suggested-edits/2434606
Vincent

39
향후이 질문을 겪고있는 임의의 Google 직원들에 대한 참고 사항 : 각도기를 사용하고이 문제에 부딪 치면이 답변이 원하는 것이 아닙니다.-각도기가 콜백을 자체적으로 호출합니다.
Vincent

그것은 내 문제를 해결했고 그것은 같은 cuplrit "복사 / 파스타"에 의해 발생했습니다
shaikh

1
@Vincent이 오류가 발생하면 각도기 사용자 문제는 무엇입니까?
Bruno Bieri

57

비동기 테스트의 경우에도이 경우에 시간 초과가 발생합니다. 비동기 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


1
이것은 "올바른 방법"이 아닌 것처럼 보이지만 Selenium 테스트를 실행하기 위해 몇 가지 추가 0을 추가 한 후 필요한 해킹이었습니다.
emery

원래 jasmine.DEFAULT_TIMEOUT_INTERVAL은 60000ms입니다. 따라서이 예제는 실제로 6 배 더 짧아집니다.
Waltari

맞습니다.이 예에서는 난수를 입력했습니다. 감사합니다 :)
gsalgadotoledo

20

이 오류는 서비스 / 공장 초기화 등을 할 때 주입을 생략하여 발생할 수도 있습니다. 예를 들어 다음을 수행하면 발생할 수 있습니다.

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

수정하려면 서비스를 올바르게 검색하기 위해 inject로 함수를 래핑하십시오.

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

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

6

karma-jasmine 플러그인을 사용하여 기본 시간 초과 간격을 전역 적으로 설정할 수 있습니다 .

karma.conf.js에이 설정을 추가하십시오

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

5

이 오류는 항상 효과가 있었던 테스트에서 저를 위해 파란색으로 시작되었습니다. Macbook이 느리게 실행되는 것을 확인할 때까지 도움이되는 제안을 찾을 수 없었습니다. CPU가 다른 프로세스에 의해 멈춰있는 것을 보았습니다. Jasmine 비동기 오류가 사라지고 테스트가 다시 한 번 정상입니다.

이유를 묻지 마십시오. 모르겠습니다. 그러나 제 상황에서는 시스템 리소스가 부족한 것 같습니다.


5
CPU가 사용 가능 해지면 기본 시간 종료 전에 작업이 완료되었을 수 있습니다. CPU가 사용 중일 때 테스트중인 작업을 완료하는 데 너무 오래 걸렸습니다.
Shane

5

이것은 답변보다 더 많은 관찰이지만, 내가 좌절했던 다른 사람들에게 도움이 될 수 있습니다.

내 스위트 룸의 두 가지 테스트 에서이 오류가 계속 발생했습니다. 나는 내가하고있는 리팩토링으로 테스트를 간단히 깨뜨렸다 고 생각했기 때문에 변경 사항을 취소 한 후에도 오류를 제거 할 것이라고 생각한 이전 코드로 두 번 수정했습니다 (두 번 수정). 그렇게해도 아무것도 바뀌지 않았습니다. 나는 어제 하루 종일 내 꼬리를 쫓아 내고 오늘 아침 문제를 해결하지 않고 일부를 쫓았습니다.

오늘 아침에 좌절해서 랩톱에서 코드를 확인했습니다. 오류없이 전체 테스트 스위트 (약 180 개 테스트)를 실행했습니다. 따라서 오류는 코드 또는 테스트에 없었습니다. 내 dev 상자로 돌아가서 문제를 일으킨 메모리의 모든 내용을 지우려면 다시 부팅하십시오. 동일한 두 테스트에서 동일한 오류가 발생하지 않습니다. 그래서 나는 내 컴퓨터에서 디렉토리를 삭제하고 다시 체크 아웃했다. 짜잔! 오류가 없습니다.

원인 또는 수정 방법을 모르지만 작업 디렉토리를 삭제하고 다시 체크 아웃하면 원래 상태가 무엇이든 고정됩니다.

이것이 누군가를 돕기를 바랍니다.


1
고마워요, 나는 이것에 열중했습니다. 나는 내 PC를 재부팅했고 그게 다였다
yngrdyn

내 경우에는 명령을 다시 실행 하여이 문제를 해결했습니다. 나는 단위 테스트를 위해 핫 리로드를했고 매번 실패했습니다. 나는 멈추고 명령을 다시 실행해야했다.
jignesh

4

를 사용하지 말고 done함수 호출을 비워 두십시오.


내가 틀렸다면 나를 수정하십시오. 그러나 이해 했으므로 테스트 스위트가 테스트 전에 완료되고 대신 오류 메시지가 덤프됩니다. 이는 어설 션이 실행되기 전에 테스트 스위트가 완료 될 때 실패한 어설 션이 테스트를 중단하지 않음을 의미합니다. 또한 다른 테스트에서이 테스트로 생성 된 오류가 표시된다는 것을 의미 할 수도 있습니다. 마지막으로 모든 것이 처음에는 괜찮아 보이지만 테스트 수가 증가함에 따라 문제가 간헐적으로 나타납니다.
LosManos

3

beforeAll함수 에서 무언가를 기대할 때도이 오류가 발생 합니다!

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

    beforeAll(function () {
        ...

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

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

    }
}

2

필자의 경우이 오류는 "fixture.detectChanges ()"를 잘못 사용하여 발생한 것입니다.이 메서드는 변경이 감지 될 때만 콜백에 응답하는 이벤트 리스너 (비동기) 인 것 같습니다. 변경 사항이 감지되지 않으면 콜백을 호출하지 않아 시간 초과 오류가 발생합니다. 도움이 되었기를 바랍니다 :)


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

0

@mastablasta가 지적했듯이 '완료'인수를 호출하거나 이름을 지정한 경우 완료되면 테스트에서 콜백 completed ()를 호출하면됩니다.

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

0

jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;

이것을 차단 상태로 유지하면 내 문제가 해결되었습니다.

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

0

내가 한 일은 다음 코드를 추가 / 업데이트했습니다.

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

3
설명없이 코드를 게시하는 대신이 코드가 작동하는 이유를 설명하십시오.
Kobe

따라서 기본적으로 테스트를 실행하고 예상보다 오래 걸리면 기본 시간 초과가 발생하고 스크립트가 실행 중에 진행되지 않기 때문에 실패합니다. 일부 조건이 충족되지 않아 발생할 수 있습니다 (예 : 가시성, 페이지로드). 이제 기본 시간 초과가 1000ms >>와 같으면 >> 스크립트가 1 초에 불과하기 때문에 자주 실패하고 스크립트 실패에 여러 가지 요인이 추가 될 수 있습니다. 그러나 시간 초과 간격을 늘리면 조건이 충족 될 때까지 브라우저 / 드라이버 대기 시간이 길어질 수 있습니다.
Zeeshan

2
좋아, 이제 당신의 게시물에 그것을 말하십시오; 설명없이 코드로 응답하지 않도록 노력해야합니다 :)
Kobe


0

테스트가 결코 오지 않는 콜백을 기다리는 것 같습니다. 비동기 동작으로 테스트가 실행되지 않았기 때문일 수 있습니다.

먼저 "it"시나리오에서 fakeAsync를 사용하는지 확인하십시오.

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

flush()microTask 대기열이 끝날 tick()때까지 또는 지정된 시간 동안 대기하는 데 사용할 수도 있습니다 .


-2

함수 done에 인수 ( ) 가 있으면 it함수 자체에서 호출하십시오.

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

4
이 답변이 왜 그렇게 유용하지 않은지에 대한 설명이 없으면.
Gary

2
이 답변은 내 문제를 해결했습니다 ... 각도 테스트는 악몽입니다!
Benjamin Caure
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.