用AngularJS和Jasmine模拟HTTP服务单元测试
我正试图构建一个模拟服务,以便我的单元测试能够验证某些函数是否被相应地调用和更新。不幸的是,我不能让它工作 Im当前收到一个错误用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
未定义不是此行的函数
:
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()
是否未定义?如果有帮助,请更新我的问题以显示我的控制器签名