Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用AngularJS和Jasmine模拟HTTP服务单元测试_Angularjs_Unit Testing_Mocking_Jasmine - Fatal编程技术网

用AngularJS和Jasmine模拟HTTP服务单元测试

用AngularJS和Jasmine模拟HTTP服务单元测试,angularjs,unit-testing,mocking,jasmine,Angularjs,Unit Testing,Mocking,Jasmine,我正试图构建一个模拟服务,以便我的单元测试能够验证某些函数是否被相应地调用和更新。不幸的是,我不能让它工作 Im当前收到一个错误未定义不是此行的函数: spyOn(statusService, 'getModuleStatus').andCallThrough(); 我的实际服务如下所示: serviceStatusServices.factory('serviceStatusAppAPIservice', function ($http) { var serviceStatusAp

我正试图构建一个模拟服务,以便我的单元测试能够验证某些函数是否被相应地调用和更新。不幸的是,我不能让它工作

Im当前收到一个错误
未定义不是此行的函数

spyOn(statusService, 'getModuleStatus').andCallThrough();
我的实际服务如下所示:

serviceStatusServices.factory('serviceStatusAppAPIservice', function ($http) {

    var serviceStatusAppAPI = {};

    serviceStatusAppAPI.getModuleStatus = function () {
        return $http({
            method: 'JSON',
            url: '/settings/getservicestatusandconfiguration'
        });
    }

    serviceStatusAppAPI.setModuleStatus = function (module) {
        return $http({
            method: 'POST',
            url: '/settings/setservicestatusandconfiguration',
            data: { moduleId: module.ModuleId, configData: module.ConfigValues }
        });
    }

    return serviceStatusAppAPI;
});
我的更新功能

serviceStatusControllers.controller('serviceStatusController', ['$scope', 'serviceStatusAppAPIservice', '$filter', '$timeout', function ($scope, serviceStatusAppAPIservice, $filter, $timeout) {

    $scope.update = function () {
        $scope.loading = true;
        serviceStatusAppAPIservice.getModuleStatus().then(function (response) {

            $scope.modules = $filter('orderBy')(response.data.moduleData, 'ModuleName')
            ...
我的测试是这样的

describe('ServiceStatusController', function () {
    beforeEach(module("serviceStatusApp"));

    var scope;
    var statusService;
    var controller;
    var q;
    var deferred;

    // define the mock people service
    beforeEach(function () {
        statusService = {
            getModuleStatus: function () {
                deferred = q.defer();
                return deferred.promise;
            }
        };
    });

    // inject the required services and instantiate the controller
    beforeEach(inject(function ($rootScope, $controller, $q) {
        scope = $rootScope.$new();
        q = $q;
        controller = $controller('serviceStatusController', { 
                     $scope: scope, serviceStatusAppAPIservice: statusService });
    }));

    describe("$scope.update", function () {
        it("Updates screen", function () {
            spyOn(statusService, 'getModuleStatus').andCallThrough();

            scope.update();

            deferred.resolve();

            expect(statusService.getModuleStatus).toHaveBeenCalled();
            expect(scope.modules).not.toBe([]);
        });
    });
});
serviceStatusAppAPI.getModuleStatus().then(function (data) {
    $scope.modules = $filter('orderBy')(data.moduleData, 'ModuleName')
})

另外,如何将从服务返回的任何模拟数据传递给调用者。目前在我的模型中,我使用
serviceStatusAppAPI.getModuleStatus(data)
,然后使用
data.data
获取返回的JSON。

我假设您在ctrl中执行类似操作

scope.update = function() {
    serviceStatusAppAPIservice.setModuleStatus(url).then(function (data) {
        scope.modules = data;
    })    
};
回报承诺的服务

.factory('serviceStatusAppAPI', function($http, $q) {
        return {
            getModuleStatus: function() {
                var defer = $q.defer();
                $http({method: 'GET', url: '/settings/getservicestatusandconfiguration'})
                    .success(function(data, status, headers, config) {
                        // this callback will be called asynchronously
                        // when the response is available
                        defer.resolve(data);
                    })
                    .error(function(data, status, headers, config) {
                        // called asynchronously if an error occurs
                        // or server returns response with an error status.
                        window.data = data;
                    });

                return defer.promise;
            }
        };
    });
所以在你的控制器中,你会得到这样的数据

describe('ServiceStatusController', function () {
    beforeEach(module("serviceStatusApp"));

    var scope;
    var statusService;
    var controller;
    var q;
    var deferred;

    // define the mock people service
    beforeEach(function () {
        statusService = {
            getModuleStatus: function () {
                deferred = q.defer();
                return deferred.promise;
            }
        };
    });

    // inject the required services and instantiate the controller
    beforeEach(inject(function ($rootScope, $controller, $q) {
        scope = $rootScope.$new();
        q = $q;
        controller = $controller('serviceStatusController', { 
                     $scope: scope, serviceStatusAppAPIservice: statusService });
    }));

    describe("$scope.update", function () {
        it("Updates screen", function () {
            spyOn(statusService, 'getModuleStatus').andCallThrough();

            scope.update();

            deferred.resolve();

            expect(statusService.getModuleStatus).toHaveBeenCalled();
            expect(scope.modules).not.toBe([]);
        });
    });
});
serviceStatusAppAPI.getModuleStatus().then(function (data) {
    $scope.modules = $filter('orderBy')(data.moduleData, 'ModuleName')
})
这就是运行单元测试用例的方法

beforeEach(function() {

    var statusService = {};

    module('myApp', function($provide) {
        $provide.value('serviceStatusAppAPIservice', statusService);
    });

    statusService.modalStatus = {
        moduleData: [{ModuleName: 'abc'}, {ModuleName: 'def'}]
    };

    inject(function ($q) {
        statusService.setModuleStatus = function () {
            var defer = $q.defer();

            defer.resolve(this.modalStatus);

            return defer.promise;
        };

        statusService.getModuleStatus = function () {
            var defer = $q.defer();

            defer.resolve(this.modalStatus);

            return defer.promise;
        };

    });
});

beforeEach(inject(function ($rootScope, $controller, _$stateParams_) {
    scope = $rootScope.$new();
    stateParams = _$stateParams_;
    controller = $controller;
}));

var myCtrl = function() {
    return controller('ServiceStatusController', {
                $scope: scope,
            });
};

it('should load status', function () {
    myCtrl();
    scope.update();
    scope.$digest();
    expect(scope.modules).toBe({
        status: 'active'
    });
});

嗨,谢谢,是的,你基本上是对的。我用我的更新功能更新了我的问题。我当前在
getModuleStatus
上遇到一个错误,请尝试提供模拟服务中所需的确切数据。我认为,既然您正在应用$filter并期望从中得到一些东西。您需要提供准确的数据,以便$filter可以过滤结果,可能是这样的{moduleData:[{moduleName:'Module1'},{moduleName:'newmodule'}}}我认为它更多地抱怨
然后
因为它说未定义不是一个函数,好像
serviceStatusAppapapapaiService.getModuleStatus()
是否未定义?如果有帮助,请更新我的问题以显示我的控制器签名