Testing JS callback with timeout using Jasmine

时间:2017-12-17 08:17:30

标签: javascript angularjs jasmine karma-jasmine

I need to test some code in Angular with Jasmine, but the thing is that I can't do this because of $timeout call. So the code looks like this:

$scope.add = function() {
    SomeService.add(id, function() {
        $timeout(function() {
            $scope.showSuccessMessage();
        }, 1000)
    }, function() {})
};

So the test code is:

    describe('method add', function() {
    it('should add', function() {
        spyOn(SomeService, 'add').and.callFake(function(id, successCallback, errorCallback) {
            spyOn(scope, 'showSuccessMessage');
            successCallback();
            expect(scope.showSuccessMessage).toHaveBeenCalled();
        });
        scope.add();
        expect(SomeService.add).toHaveBeenCalled();
    });
});

And the problem is that because of the timeout call I can't check that showSuccessMessage() has been called. I know about Jasmine's ability to work with timeouts but in that case I can't find a working way because of calling it in the callback. So that's why I need help. Thanks.

2 个答案:

答案 0 :(得分:2)

您可以在调用原始函数后使用$timeout.flush() flush超时。这应该允许您访问successCallback

另外,我会将spy的{​​{1}}和expect置于另一个showSuccessMessage之外

spy

答案 1 :(得分:1)

Im not very familiar with the workings of angular, I hope this helps:

You can use the done function for asynchronous code:



    it('should add', function (done) {
        $scope.successCallback = function () {
            // successCallback was called
            done();
        }

        $scope.add();
    });