AngularJS service returning promise unit test gives error No more request expected

Posted by softweave on Stack Overflow See other posts from Stack Overflow or by softweave
Published on 2014-05-26T14:58:30Z Indexed on 2014/05/27 9:26 UTC
Read the original article Hit count: 270

Filed under:
|
|

I want to test a service (Bar) that invokes another service (Foo) and returns a promise. The test is currently failing with this error:

    Error: Unexpected request: GET foo.json
    No more request expected

Here are the service definitions:

// Foo service returns new objects having get function returning a promise   
angular.module('foo', []).
    factory('Foo', ['$http', function ($http) {
        function FooFactory(config) {
            var Foo = function (config) {
                angular.extend(this, config);
            };
            Foo.prototype = {
                get: function (url, params, successFn, errorFn) {
                    successFn = successFn || function (response) {};
                    errorFn = errorFn || function (response) {};
                    return $http.get(url, {}).then(successFn, errorFn);
                }
            };
            return new Foo(config);
        };
        return FooFactory;
    }]);

// Bar service uses Foo service
angular.module('bar', ['foo']).
    factory('Bar', ['Foo', function (Foo) {
        var foo = Foo();
        return {
            getCurrentTime: function () {
                return foo.get('foo.json', {}, function (response) {
                    return Date.parse(response.data.now);
                });
            }
        };
    }]);

Here is my current test:

'use strict';
describe('bar tests', function () {

    var currentTime, currentTimeInMs, $q, $rootScope, mockFoo, mockFooFactory, Foo, Bar, now;

    currentTime = "March 26, 2014 13:10 UTC";
    currentTimeInMs = Date.parse(currentTime);

    beforeEach(function () {

        // stub out enough of Foo to satisfy Bar service:

        // create mock object with function get: function(url, params, successFn, errorFn) 
        // that promises to return a response with this property 
        // { data: { now: "March 26, 2014 13:10 UTC" }})
        mockFoo = {
            get: function (url, params, successFn, errorFn) {
                successFn = successFn || function (response) {};
                errorFn = errorFn || function (response) {};
                // setup deferred promise
                var deferred = $q.defer();
                deferred.resolve({data: { now: currentTime }});
                return (deferred.promise).then(successFn, errorFn);
            }
        };

        // create mock Foo service
        mockFooFactory = function(config) {
            return mockFoo;
        };

        module(function ($provide) {
            $provide.value('Foo', mockFooFactory);
        });

        module('bar');

        inject(function (_$q_, _$rootScope_, _Foo_, _Bar_) {
            $q = _$q_;
            $rootScope = _$rootScope_;
            Foo = _Foo_;
            Bar = _Bar_;
        });
    });

    it('getCurrentTime should return currentTimeInMs', function () {
        Bar.getCurrentTime().then(function (serverCurrentTime) {
            now = serverCurrentTime;
        });
        $rootScope.$apply();    // resolve Bar promise
        expect(now).toEqual(currentTimeInMs);
    });

});

The error is being thrown at $rootScope.$apply(). I also tried using $rootScope.$digest(), but it gives the same error.

Thanks in advance for any insight you can give me.

© Stack Overflow or respective owner

Related posts about angularjs

Related posts about unit-testing