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.