简体   繁体   中英

Testing an Angular Promise with Jasmine

The following test keeps failing and I can't figure out why? I am trying to figure out how to test defereds/promises with Jasmine.

Error

Expected undefined to be 'Resolved Data'.

Test

    describe('Queued Repository', function () {
    var ctrl,
        rootScope,
        scope,
        service;

    beforeEach(function () {
        module('testApp');

        inject(function ($rootScope, $controller, TestSrvc) {
            rootScope = $rootScope;
            scope = $rootScope.$new();
            service = TestSrvc;
        });
    });

    afterEach(inject(function ($rootScope) {
        $rootScope.$apply();
    }));

    it('test something', function () {
        expect(service.calculate(1, 5)).toBe(6);
    });

    it('resolves promises', function () {
        var result;

        service.getPromise().then(function (data) {
            result = data;
        });

        rootScope.$apply();
        expect(result).toBe('Resolved Data');
    });
});

Service

    var app = angular.module('testApp', []);

app.service('TestSrvc', ['$q', '$timeout', '$http', function ($q, $timeout, $http) {
    return {
        getPromise: function () {
            var d = $q.defer();

            $timeout(function () {
                d.resolve('Defered Result');
            }, 5000);

            return d.promise;
        },
        getSomething: function () {
            return "Test";
        },
        calculate: function (x, y) {
            return x + y;
        }
    }
}]);

Try calling $timeout.flush() before expect(result).toBe('Resolved Data'); .

In your example, you will need to call both $timeout.flush() AND $rootScope.$apply() .

Explanation: $timeout.flush() will force your $timeout in the service to run immediately. Your service will then call ' resolve ' - but the promise.then() will not be called until the subsequent digest cycle; therefore you will need to call $rootScope.$apply() to propagate any 'resolves' and 'watches' - which will occur synchronously.

NOTE: In Jasmine, ensure that your promise.then() function appears BEFORE your call to $rootScope.$apply otherwise it will not fire the promise.then() function. (I haven't figured out why this is the case in Jasmine.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM