mardi 8 décembre 2015

Unit testing an Angular Controller with a route resolve that returns a promise with $resource

I am having trouble unit testing a controller that is using resolve on a service that returns a $resource. Inside the controller, I am waiting for the promise from the service to resolve before setting it to my $scope variable but I am not sure how to mock the resolve property to make the tests pass.

The controller I am trying to test

angular.module('app')
  .config(['$routeProvider', function($routeProvider) {
    $routeProvider
        .when('/settings', {
            templateUrl: '/views/settings.html',
            controller:'SettingsCtrl',
            resolve: {
                settings: ['SettingsService', function (SettingsService) {
                    return SettingsService.get(
                        function(response) {
                            console.log('success');
                        },
                        function(err) {
                            console.log('error');
                        }
                    )
                }]
            }
        });
    }])
    .controller('SettingsCtrl', ['$scope', 'settings', 
      function($scope, settings) {
      settings.$promise.then(
        function(data) {
            $scope.settings = data;
        },
        function (err) {
            console.log('error');
            console.log(err);
        }
      );
    }]); 

and the service

angular.module('app')
    .factory('SettingsService', ['$resource', function ($resource) {
        return $resource('/api/settings', {}, {
            get: {method: 'GET'},
        });
    }]);

current attempt which returns cannot read property then of undefined.

describe('Testing SettingsController with resolve', function() {

    beforeEach(module('app'));

    beforeEach(inject(function(_$rootScope_, $controller, _$q_) {
        $scope = _$rootScope_.$new();
        $rootScope = _$rootScope_;
        $q = _$q_;

        mockSettingsService = function() {
            deferred = _$q_.defer();
            return {$promise: deferred.promise};
        }

        $controller('SettingsCtrl', {
            $scope: $scope,
            settings: mockSettingsService
        });
    }));

    it('should retrieve the data', function() {
        var mockResponse = {data: 'data'}
        deferred.resolve(mockResponse);
        $rootScope.$apply();

        expect($scope.settings).toEqual(mockResponse);
    });
});

I know how to test a controller that has the service injected it by mocking the service but I still would like to know how to test a controller that resolves a service that returns a promise.

Aucun commentaire:

Enregistrer un commentaire