【问题标题】:Angular unit testing controller $scope lengthAngular 单元测试控制器 $scope 长度
【发布时间】:2016-05-25 18:22:23
【问题描述】:

我正在尝试使用通过 $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 采用不同的方法,我从单元测试开始,我有点迷茫,有人可以帮忙吗?

【问题讨论】:

  • $http get 请求是异步的,因此很可能请求工作正常,但是当您的测试运行时,请求的结果并没有得到解决。 $scope.$apply() 可能会有所帮助,但我不必为 Angular 编写单元测试。

标签: javascript angularjs unit-testing


【解决方案1】:

这可能会使代码工作:

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

但我认为实际上创建一个虚假的 Promise 更具可读性并且更不容易出错 - 像这样:

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

【讨论】:

    猜你喜欢
    • 2014-05-17
    • 2016-07-29
    • 2015-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多