如何对具有多个$resource调用的角度控制器进行单元测试
How to unit test angular controller having multiple $resource calls
我有一个控制器,它在初始化时对后端执行多个$resource调用。这很好,但现在我需要使用jasmine添加单元测试,问题来了,当我试图在控制器中保存对象的状态时,我遇到了一个错误。
在控制器初始化时,我调用3$resource来填充3个下拉列表,在对3个下拉菜单进行选择并在另一个输入文本中输入值后,我按下submit(保存),我的实体就被保存了。
我在angular方面没有太多经验,所以我真的需要帮助,如果需要其他资源,只要问一下,我就会把它们添加到这个帖子中。谢谢
现在我需要对这个保存功能进行单元测试,我得到了一个错误:
Chrome 41.0.2272 (Windows 7) permissionController should call the service successfully FAILED
Error: Unexpected request: POST http://localhost:8080/webapp-1.0.0-SNAPSHOT/v1/actions/search
No more request expected
at $httpBackend (C:/_workspace/webapp/Platform/ui/src/main/uidev/node_modules/angular-mocks/angular-mocks.js:1220:9)
at sendReq (C:/_workspace/webapp/Platform/ui/src/main/uidev/app/lib/js/angular.js:9628:9)
at serverRequest (C:/_workspace/webapp/Platform/ui/src/main/uidev/app/lib/js/angular.js:9344:16)
at processQueue (C:/_workspace/webapp/Platform/ui/src/main/uidev/app/lib/js/angular.js:13189:27)
at C:/_workspace/webapp/Platform/ui/src/main/uidev/app/lib/js/angular.js:13205:27
at Scope.$eval (C:/_workspace/webapp/Platform/ui/src/main/uidev/app/lib/js/angular.js:14401:28)
at Scope.$digest (C:/_workspace/webapp/Platform/ui/src/main/uidev/app/lib/js/angular.js:14217:31)
at Function.$httpBackend.flush (C:/_workspace/webapp/Platform/ui/src/main/uidev/node_modules/angular-mocks/angular-mocks.js:1519:38)
at Object.<anonymous> (C:/_workspace/webapp/Platform/ui/src/main/uidev/test/unit/authz/permission/create-permission-controller-test.js:28:21)
这是控制器:
angular.module('platform.authz').controller('permissionController', function($translatePartialLoader,
PermissionService, ActionService, ResourceService, EnvironmentService, $scope, $state) {
'use strict';
$translatePartialLoader.addPart('authz/permission');
var controller = this;
controller.permission = {};
function errorMessageHandler(response) {
var errorMessages = [];
response.data.messages.forEach(function(message, i) {
errorMessages[i] = {type: 'danger', text: message.description};
});
controller.notificationMessages = errorMessages;
}
controller.populateActions = function() {
ActionService.searchRequestObject().search({search: ''}).$promise.then(function(data) {
controller.actions = data;
}, errorMessageHandler);
};
controller.populateResources = function() {
ResourceService.searchRequestObject().search({search: ''}).$promise.then(function(data) {
controller.resources = data;
}, errorMessageHandler);
};
controller.populateEnvironments = function() {
EnvironmentService.searchRequestObject().search({search: ''}).$promise.then(function(data) {
controller.environments = data;
}, errorMessageHandler);
};
controller.getPermissionSaveRequest = function() {
var permissionSaveRequest = {};
permissionSaveRequest.name = controller.permission.name;
permissionSaveRequest.actionId = controller.permission.action.id;
permissionSaveRequest.resourceId = controller.permission.resource.id;
permissionSaveRequest.environmentId = controller.permission.environment.id;
return permissionSaveRequest;
};
controller.save = function() {
PermissionService.createRequestObject().create(controller.getPermissionSaveRequest()).$promise.then(function() {
controller.notificationMessages = [
{type: 'success', text: 'Save has been successful!'}
];
controller.permission = {};
$scope.permissionDetailsForm.$setPristine();
}, errorMessageHandler);
};
controller.cancel = function cancel() {
$state.reload();
};
controller.actions = controller.populateActions();
controller.resources = controller.populateResources();
controller.environments = controller.populateEnvironments();
});
这是控制器初始化时调用的服务之一(所有3个服务看起来都一样)
angular.module('platform.authz').factory('ActionService', function($resource, $log, configService) {
'use strict';
return {
searchRequestObject: function() {
return $resource(configService.getUrlForService('action') + '/' + 'search', {}, {
search: {method: 'POST', isArray: true}
});
}
};
});
这是我的单元测试试用版:
describe('permissionController', function() {
'use strict';
var httpBackend, permissionController, state, scope;
beforeEach(module('platform'));
beforeEach(inject(function(_$httpBackend_, $controller, _$state_, configService, $rootScope) {
state = _$state_;
spyOn(state, 'go');
spyOn(state, 'transitionTo');
spyOn(configService, 'getUrlForService')
.and.callFake(function(name) {
return CONFIG.get('MAIN_URL_FOR_REST_SERVICES') + name + 's';
}
);
httpBackend = _$httpBackend_;
scope = $rootScope.$new();
permissionController = $controller('permissionController', {$scope: scope});
}));
it('should call the service successfully', function() {
permissionController.permission = {'name': 'all', 'action': {'id': 1, 'name': 'all'}, 'resource': {'id': 1, 'name': 'all'}, 'environment': {'id': 1, 'name': 'all'}};
httpBackend
.whenPOST(CONFIG.get('MAIN_URL_FOR_REST_SERVICES') + 'permissions', permissionController.getPermissionSaveRequest())
.respond(200, 'created');
permissionController.save();
httpBackend.flush();
expect(permissionController.errorMessages[0].text).toBe('Error');
});
});
问题是在加载控制器时进行3$resource调用,在执行测试时加载控制器。因此,您应该确保(例如在beforeEach中)也模拟那些后端调用。当按下save时,您现在只是在嘲笑您所期望的,但在save事件之前,您的控制器已经在进行一些后端通信。您得到的异常告诉您:"意外请求"。
修复程序在这里:
describe('permissionController', function() {
'use strict';
var $httpBackend, permissionController, scope;
beforeEach(module('platform'));
beforeEach(inject(function($injector, _$state_, configService) {
$httpBackend = $injector.get('$httpBackend');
scope = $injector.get('$rootScope').$new();
scope.permissionDetailsForm = {$setPristine: function() {
}};
var state = _$state_;
spyOn(state, 'go');
spyOn(state, 'transitionTo');
spyOn(configService, 'getUrlForService')
.and.callFake(function(name) {
return CONFIG.get('MAIN_URL_FOR_REST_SERVICES') + name + 's';
}
);
var $controller = $injector.get('$controller');
$httpBackend.when('POST', CONFIG.get('MAIN_URL_FOR_REST_SERVICES') + 'actions/search').respond(200,
'[{"name": "all","id": "1"}]'
);
$httpBackend.when('POST', CONFIG.get('MAIN_URL_FOR_REST_SERVICES') + 'resources/search').respond(200,
'[{"name": "all","id": "1"}]'
);
$httpBackend.when('POST', CONFIG.get('MAIN_URL_FOR_REST_SERVICES') + 'environments/search').respond(200,
'[{"name": "all","id": "1"}]'
);
permissionController = $controller('permissionController', {$scope: scope});
$httpBackend.flush();
}));
it('should call the service successfully', function() {
permissionController.permission =
{'name': 'all', 'action': {'id': 1, 'name': 'all'}, 'resource': {'id': 1, 'name': 'all'},
'environment': {'id': 1, 'name': 'all'}};
$httpBackend
.whenPOST(CONFIG.get('MAIN_URL_FOR_REST_SERVICES') + 'permissions',
permissionController.getPermissionSaveRequest())
.respond(200, 'created');
permissionController.save();
$httpBackend.flush();
expect(permissionController.notificationMessages[0].text).toBe('Save has been successful!');
});
});
相关文章:
- 如何在Angular单元测试中从另一个控制器的rootScope将方法添加到rootScope中
- 如何对具有多个$resource调用的角度控制器进行单元测试
- 角度单元测试控制器
- 控制器中的离子单元测试,spyOn未通过
- 如何在单元测试中注入Angular控制器
- 如何在AngularJS中承诺控制器后进行单元测试
- AngularJs的单元测试失败是因为Karma没有'无法识别$scope$控制器中的侦听器
- Angular.js中的控制器单元测试
- 角度单元测试:如何在没有范围的情况下测试控制器属性
- 单元测试AngularJS控制器,同时遵循最佳实践
- 使用特定语法对控制器进行单元测试
- Angularjs 单元测试控制器 orderBy.
- 在 angularjs 控制器中对承诺调用进行单元测试时遇到问题
- 单元测试控制器,在控制器中具有 $state.go 方法
- 依赖于 AngularJS 中表单验证的单元测试控制器
- 如何在对 AngularJS 控制器进行单元测试时模拟网络延迟
- 角度指令控制器单元测试使用窗口.确认
- Angularjs,Karma控制器单元测试注入器:modulerr
- 如何在Ember.js的控制器单元测试中设置模型数据
- 在AngularJS中模拟控制器单元测试的依赖服务