Testing Angular promises with Jasmine

Example of testing a promise taken from http://docs.angularjs.org/api/ng.$q

by Tyler Eich

HTML

<script src="http://code.angularjs.org/1.2.9/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine-html.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/boot.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular-mock.js"></script>
<body></body>

JavaScript

angular.module('app', ['ngMock']);

describe('AngularJS and Jasmine', function() {
    var $q, $timeout;

    beforeEach(function() {
        module('app');
        inject(function(_$q_, _$timeout_) {
            // Set `$q` and `$timeout` before tests run
            $q = _$q_;
            $timeout = _$timeout_;
        });
    });

    // Putting `done` as argument allows async testing
    it('Demonstrates asynchronous testing', function(done) {
        var deferred = $q.defer();
    
        $timeout(function() {
            deferred.resolve('I told you I would come!');
        }, 1000); // This won't actually wait for 1 second.
                  // `$timeout.flush()` will force it to execute.
    
        deferred.promise.then(function(value) {
            // Tests set within `then` function of promise
            expect(value).toBe('I told you I would come!');
        })
        // IMPORTANT: `done` must be called after promise is resolved
        .finally(done);
    
        $timeout.flush(); // Force digest cycle to resolve promises
    });
});