itsource

쟈스민 모크 클럭으로 $timeout을 사용하는 Unit Testing Angular 서비스

mycopycode 2023. 3. 28. 21:46
반응형

쟈스민 모크 클럭으로 $timeout을 사용하는 Unit Testing Angular 서비스

앵귤러 서비스 중 하나에 정기적으로 반복 호출하고 싶은 함수가 있습니다.$timeout을 사용해 주세요.다음과 같습니다.

var interval = 1000; // Or something

var _tick = function () {
     $timeout(function () {
        doStuff();
        _tick();
    }, interval);
};

_tick();

저는 지금 재스민과의 유닛 테스트 방법에 대해 고민하고 있습니다.어떻게 하면 좋을까요?사용하는 경우$timeout.flush()함수 호출이 무기한으로 발생합니다.재스민 모조시계를 쓰면$timeout영향을 받지 않는 것 같아요.기본적으로 이 작업을 수행할 수 있다면 다음 작업을 수행할 수 있습니다.

describe("ANGULAR Manually ticking the Jasmine Mock Clock", function() {
    var timerCallback, $timeout;

    beforeEach(inject(function($injector) {
        $timeout = $injector.get('$timeout');
        timerCallback = jasmine.createSpy('timerCallback');
        jasmine.Clock.useMock();
    }));

    it("causes a timeout to be called synchronously", function() {
        $timeout(function() {
            timerCallback();
        }, 100);
        expect(timerCallback).not.toHaveBeenCalled();
        jasmine.Clock.tick(101);
        expect(timerCallback).toHaveBeenCalled();
    });
});

다음 두 가지 변형은 작동하지만 도움이 되지 않습니다.

describe("Manually ticking the Jasmine Mock Clock", function() {
    var timerCallback;

    beforeEach(function() {
        timerCallback = jasmine.createSpy('timerCallback');
        jasmine.Clock.useMock();
    });

    it("causes a timeout to be called synchronously", function() {
        setTimeout(function() {
            timerCallback();
        }, 100);
        expect(timerCallback).not.toHaveBeenCalled();
        jasmine.Clock.tick(101);
        expect(timerCallback).toHaveBeenCalled();
    });
});

describe("ANGULAR Manually flushing $timeout", function() {
    var timerCallback, $timeout;

    beforeEach(inject(function($injector) {
        $timeout = $injector.get('$timeout');
        timerCallback = jasmine.createSpy('timerCallback');
    }));

    it("causes a timeout to be called synchronously", function() {
        $timeout(function() {
            timerCallback();
        }, 100);
        expect(timerCallback).not.toHaveBeenCalled();
        $timeout.flush();
        expect(timerCallback).toHaveBeenCalled();
    });
});

잘 부탁드립니다!

재스민 시계를 사용하여 시험을 비동기화하지 마십시오.대신,$timeout.flush()테스트의 흐름을 동기적으로 유지합니다.셋업은 조금 까다로울 수 있지만, 일단 취득하면 테스트가 고속화되고 제어됩니다.

다음은 이 방법을 사용하여 테스트를 수행하는 예입니다.https://github.com/angular/angular.js/blob/master/test/ngAnimate/animateSpec.js#L618

@matsko의 대답은 나를 올바른 길로 인도했다.답을 쉽게 찾을 수 있도록 "완전한" 솔루션을 게시하려고 했습니다.

테스트 대상

angular.module("app").service("MyService", function() {
    return {
        methodThatHasTimeoutAndReturnsAPromise: function($q, $timeout) {
            var deferred = $q.defer();
            $timeout(function() {
                deferred.resolve(5);
            }, 2000);
            return deferred.promise;
        }
    };
});

테스트

describe("MyService", function() {
    var target,
        $timeout;
    beforeEach(inject(function(_$timeout_, MyService) {
        $timeout = _$timeout_;
        target = MyService;
    }));
    beforeEach(function(done) {
        done();
    });
    it("equals 5", function(done) {
        target.methodThatHasTimeoutAndReturnsAPromise().then(function(value) {
            expect(value).toBe(5);
            done();
        });
        $timeout.flush();
    });
});

언급URL : https://stackoverflow.com/questions/17418716/unit-testing-angular-service-that-uses-timeout-with-jasmines-mock-clock

반응형