如何测试具有服务的Angular控制器

时间:2016-05-16 06:36:51

标签: angularjs unit-testing

我有一个控制器和服务如下

(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);

}())

我创建了一个类似下面的模拟服务,用于模拟单元测试服务。

(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;

        });
}());

我的测试用例就像

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);
        });
    });

});

问题是控制器中的then方法没有被调用。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

要修理的三件事......

  1. 不要嵌套beforeEach来电。您可以使用module初始化多个模块。

    beforeEach(function() {
        module('MockApp', 'mock.service');
        // and so on
    
  2. 您的模拟数据与您从基于$http的承诺回复中看到的数据不完全匹配

    return $q.when({data: mydata});
    
  3. 为了处理承诺,您需要触发摘要周期

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