2

I am having a controller and service like below

(function () {

    var mockController = function ($scope, MockService) {
        $scope.message = "This is a text message";

        $scope.getCities = function () {
            $scope.places = [];
            MockService.getCities().then(function (response) {
                var places = response.data["weather-app:root"].city;
                if (places) {
                    if (Array.isArray(places)) {
                        $scope.places = places;
                    } else {
                        $scope.places.push(places);
                    }
                }
            });
        };

    };


    var mockService = function ($http) {
        this.getCities = function () {
            return $http.get("../rest/url", {
                headers: {
                    'Accept': 'application/yang.data+json'
                }
            });
        };
    };

    angular.module("MockApp", [])
        .service("MockService", mockService)
        .controller("MockController", mockController);

}())

I created a mock service like below for mocking the service for unit testing.

(function () {
    angular.module('mock.service', [])
        .service('MockService', function ($q) {
            var mockService = {};
            mockService.getCities = function () {
                var mydata = {
                    "weather-app:root": {
                        "city": [
                            {
                                "city-name": "Chennai"
                                , "country-name": "India"
                            }




                            , {
                                "city-name": "Mangalore"
                                , "country-name": "India"
                                }
                                ]
                    }
                }
                return $q.when(mydata);
            };
            return mockService;

        });
}());

My test case is like

describe("MockController", function () {

    var $scope;

    beforeEach(function () {
        module("MockApp");
        beforeEach(module('mock.service'));

        inject(function (_$controller_, _$rootScope_, _MockService_) {
            $scope = _$rootScope_.$new();
            controller = _$controller_("MockController", {
                $scope: $scope
                , MockService: _MockService_
            });

        });
    });

    describe("Test", function () {

        it("Should be Bangalore", function () {
            $scope.getCities();
            console.log($scope.places);
        });
    });

});

the problem is that the then method in controller is not getting called. How can I resolve the issue ?

robin
  • 1,893
  • 1
  • 18
  • 38
  • Possible duplicate of [Unit-test promise-based code in Angular](http://stackoverflow.com/questions/16081586/unit-test-promise-based-code-in-angular) – Phil May 16 '16 at 06:44
  • @Phil where should i call it if i call it in the beforeeach its throwing error saying apply not function – robin May 16 '16 at 06:55
  • Whoops, was meant to be `$scope.$apply()` (forgot a `$`). In any case, I saw another problem so compiled it all into an answer. – Phil May 16 '16 at 07:03

1 Answers1

1

Three things to fix...

  1. Don't nest the beforeEach calls. You can init multiple modules with module.

    beforeEach(function() {
        module('MockApp', 'mock.service');
        // and so on
    
  2. Your mock data does not quite match what you'd see from an $http based promise response

    return $q.when({data: mydata});
    
  3. In order to process promises, you need to trigger a digest cycle

    it("Should be Bangalore", function() {
        $scope.getCities();
        $scope.$apply();
        console.log($scope.places);
    });
    
Phil
  • 157,677
  • 23
  • 242
  • 245