简体   繁体   中英

Angular Jasmine unit test for promise

I want to write a unit test that just displays the behavior of creating two promises, wrapping them up into one with $q.all and then test that the promises are both resolved at the same time.

  describe("Application controller", function() {
    var scope;
    var controller;

    beforeEach(module('my.namespace'));
//this suite can be removed.
    describe("Application ", function() {
        beforeEach(
            inject(function ($rootScope, $controller,$q) {
                scope = $rootScope.$new();
                controller = $controller('Application', {
                    '$scope': scope
                });
            }));


        it("should package two promises into one", function (done) {
            inject(function ($rootScope) {
                setTimeout(function () {
                    $rootScope.$apply(function () {
                        var promiseOne = $q.defer(),
                            //promiseOneData;
                            promiseTwo = $q.defer();
                            //promiseTwoData
                        promiseOne.then(function(data){
                            promiseOne.resolve('promiseOne');
                            expect(1).toBe(1);
                        });
                        promiseTwo.then(function(data){
                            promiseTwoData.resolve('promiseTwo');
                        })
                        var allPromises = $q.all([promiseOne,promiseTwo]);
                        allPromises.then(function(data){
                            //data should contain an array of two empty elements for each promise
                            expect(data.length).toBe(2);
                        });
                        done();
                    });
                }, 1000);


    })
});

With this I get the error: Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL. I don't want to actually use a get request for anything here, I just need two promises to be resolved and then moved into one promise that contains both. How can I do that with Angular and jasmine?

What you want is probably a spy and to see if it has been called or not.

describe('test $q', function() {
  var
    $scope;
    $controller;
    $httpBackend;

  beforeEach(function() {
    module('myModule');
    inject(function(_$rootScope_, _$controller_) {
        $scope = _$rootScope_.$new();
        $controller = _$controller_;
        $controller ('MyCtrl', {
          $scope: $scope
        });
    });

  it('should test that $q.all calls callback when dependent promises are resolved', function() {
    var deferOne = $q.defer(),
        deferTwo = $q.defer();
        combinedSpy = jasmine.createSpy('combined');    

    $q.all([deferOne.promise, deferTwo.promise]).then(combinedSpy);

    expect(combinedSpy).toNotHaveBeenCalled();
    deferOne.resolve();
    deferTwo.resolve();
    $scope.apply();
    expect(combinedSpy).toHaveBeenCalled();
  });

This test title is pretty confusing, you are not simulating a promise. You are testing a promise. And you don't have to, there are already tests for $q in Angular itself, so there is no point in you writing tests for that?

wrapping them up into one with $q.all

That creates a third promise. The third promise is resolved when both promise A and B have been resolved.

test that the promises are both resolved at the same time

JavaScript is single threaded, they cannot be resolved at the same time. The third promise, the one that is created by $q.all(), will be resolved when the first and second have both been resolved. Time may pass between A and B being resolved.

Say that A is resolved, an hour later B is resolved. Then C ($q.all) will be resolved in the next digest cycle (by $scope.apply()).

This is the OP's answer that they pasted into the question:

it("Should simulate promise",inject(function($q, $rootScope){
            var deferred = $q.defer();
            var promise = deferred.promise;
            var resolvedValue;
            promise.then(function(value){
                resolvedValue  = value;
            });
            //made no promises yet
            expect(resolvedValue).toBeUndefined();
            var application = {
                id: '123',
                name: 'suebalu',
                database: '234',
                folder: 'c:',
                version: '1.2',
                file: 'previewPubFile',
                date: '2009-01-01'
            };

            deferred.resolve({
                id: '123',
                name: 'suebalu',
                database: '234',
                folder: 'c:',
                version: '1.2',
                file: 'previewPubFile',
                date: '2009-01-01'
            });
            $rootScope.$apply();
            expect(resolvedValue).toEqual(application);
        }));

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