角度单位测试控制器$范围长度

时间:2016-05-25 18:22:23

标签: javascript angularjs unit-testing

我正在尝试使用$ http,

获取一些数据的服务来测试控制器

storesController.js

(function () {
    var app = angular.module('storesController', ['storesService']);

    app.controller('StoresListController', function ($scope, StoresService) {

        $scope.getStores = function () {
            StoresService.getStores().then(function (data) {
                $scope.stores = data.data;
            });
        };
        $scope.getStores();

        $scope.deleteStore = function (id) {
            StoresService.deleteStore(id).then(function () {
                $scope.getStores();
            });

        };
    });
})()

storesService.js

(function () {
    var app = angular.module('storesService', []);

    app.factory('StoresService', ['$http','appConfig', function ($http,appConfig) {

            var webServiceUrl = appConfig.webServiceUrl;
            var stores = [];

            stores.getStores = function () {
               return $http.get(webServiceUrl + 'getStores');
            };            
            return stores;

        }]);

})();

和我的测试

describe("Store Controller", function () {
var StoresService, createController, scope;

beforeEach(function () {
    module('storesController');
    module(function ($provide) {
        $provide.value('StoresService', {
            getStores: function () {
                return {
                    then: function (callback) {
                        return callback([
                            {name: "testName", country: "testCountry"},
                            {name: "testName2", country: "testCountry2"},
                            {name: "testName3", country: "testCountry3"},
                        ]);
                    }
                };
            },
        });
        return null;
    });
});

beforeEach(function () {
    inject(function ($controller, $rootScope, _StoresService_) {
        scope = $rootScope.$new();
        StoresService = _StoresService_;
        createController = function () {
            return $controller("StoresListController", {
                $scope: scope,
            });
        };
    });
});

it("should call the store service to retrieve the store list", function () {
    createController();
    expect(scope.stores.length).toBe(3);
});

});

我正在尝试测试当创建控制器时,调用方法$ scope.getStores()并且变量$ scope.stores是一个长度为3的对象。我尝试了几种方法来测试它但是我无法使它工作,得到这个错误

TypeError: scope.stores is undefined 

也许我应该用$ httpBackend采用不同的方法,我从单元测试开始,我有点迷失,有人可以伸手吗?

1 个答案:

答案 0 :(得分:1)

这可能会使代码工作:

return callback({ data: [
                            {name: "testName", country: "testCountry"},
                            {name: "testName2", country: "testCountry2"},
                            {name: "testName3", country: "testCountry3"},
                        ]}); 

但我认为实际创建假承诺更具可读性且不易出错 - 如下所示:

describe("Store Controller", function () {
    var StoresService, createController, scope, $q;

    beforeEach(function () {
        module('storesController');
        module(function ($provide) {
            $provide.value('StoresService', {
                getStores: function () {},
            });
            return null;
        });
    });

    beforeEach(function () {
        inject(function ($controller, $rootScope, _StoresService_, _$q_) {
            $q = _$q_;
            scope = $rootScope.$new();
            StoresService = _StoresService_;
            createController = function () {
                return $controller("StoresListController", {
                    $scope: scope,
                });
            };
        });
    });

    it("should call the store service to retrieve the store list", function () {
        var deferred = $q.defer();
        // Return fake promise.
        spyOn(StoresService, 'getStores').and.returnValue(deferred.promise);

        createController();
        // Resolve fake promise with some data.
        deferred.resolve({ data: 'some data'});
        // Callback from promise wont execute without digest:
        $rootScope.$digest();

        expect(scope.stores).toEqual('some data');
    });
    });