Lloyd Banks
Lloyd Banks

Reputation: 36659

AngularJS Testing - Testing Out Logic in Promise Callback

I have the following function in my controller:

$scope.submitNote = function(){
    myService.addNote($scope.note).then(function(data){
        if(data.success === true){
            $scope.note = null;
        }
        else{
            // API call failed
        }
    }, function(){
        // Promise call failed
    });
};

I set up my testing environment with:

// Mock out fake service
beforeEach(function(){
    myService = {
        addNote: function(){
            deferred = q.defer();
            deferred.resolve({
                success: true
            });
            return deferred.promise;
        }
    };
    spyOn(myService, 'addNote').and.callThrough();
});

// Assign controller scope
beforeEach(inject(function($controller, $rootScope, $q){
    q = $q;
    scope = $rootScope.$new();
    $controller('myController', {
        $scope: scope,
        myService: myService
    });
}));

Then test out my submitNote() function with:

describe('submitNote Test', function(){
    it('should set scope.note to null after successful service call', function(){
        scope.submitNote();
        expect(myService.addNote).toHaveBeenCalled();
        expect(scope.note).toBe(null);
    });
});

The first expect passes, but the second expect does not. It looks like the then() callback from my submitNote() function isn't being called in the test.

How do I make sure the promise callback in the original function is called?

Upvotes: 2

Views: 1899

Answers (1)

tasseKATT
tasseKATT

Reputation: 38490

To give you cleaner tests that you have more control over the ngMock module extends various core services so they can be inspected and controlled in a synchronous manner.

Promise callbacks are executed during the digest loop, which in your testing environment you need to start manually.

For example:

describe('submitNote Test', function () {
    it('should set scope.note to null after successful service call', function () {

        scope.submitNote();
        scope.$digest();

        expect(myService.addNote).toHaveBeenCalled();
        expect(scope.note).toBe(null);
    });
});

Upvotes: 3

Related Questions