Jasmine - 测试函数调用变量
Jasmine - test function invoking variable
我正在尝试测试通过 angular 控制器中的局部变量调用服务方法时的场景。
在这种情况下,当项目数组为 0 时,将通过模态服务触发创建新项目模态。
控制器:
(function() {
'use strict';
angular
.module('app')
.controller('Item', Item);
//items is resolved through the ui-router resolve
//items contains a array of item objects. Will be an empty array if there are no items for that user
Item.$inject = ['items', 'modalService'];
function Item(items, modalService) {
var vm = this;
vm.items = items;
vm.newItemModal = modalService.newItemModal;
if (vm.items !== undefined) {
if (vm.items.length === 0) {
vm.newItemModal();
}
}
}
})();
vm.newItemModal() 触发要显示的新项目模式。但是,如何在 jasmine 中测试这种情况?
目前测试:
describe('Controller: Item', function(){
var scope,
ctrl,
items,
modalService,
mockItems = [{ name: 'item1', desc:'desc1'}, { name: 'item2', desc:'desc2'}];
//mocking the modalService
beforeEach(function(){
module(function($provide){
modalService = {
newItemModal: function(){
return;
}
};
$provide.value('modalService', modalService);
});
});
beforeEach(inject(function(_$rootScope_, $controller) {
$rootScope = _$rootScope_;
scope = $rootScope.$new();
ctrl = $controller('Item as item', {
$scope: scope,
items: mockItems
});
}));
it('should verify the vm object', function(){
expect(scope.item.newItemModal).toBeDefined();
expect(scope.item.items).toEqual(mockItems);
});
//Separate test-suite as items is initialised with an empty array
describe('new item modal', function(){
beforeEach(inject(function(_$rootScope_, $controller) {
$rootScope = _$rootScope_;
scope = $rootScope.$new();
ctrl = $controller('Item as item', {
$scope: scope,
items: []
});
it('should open a new item modal', function(){
//returns 0
console.log('Items length', scope.items.length);
spyOn(scope.item, 'newItemModal').and.callThrough();
//testing this assertion fails
expect(scope.item.newItemModal).toHaveBeenCalled();
});
}));
});
});
问题是当下面一行被执行时:
spyOn(scope.item, 'newItemModal').and.callThrough();
控制器已创建,代码已执行。
您需要在创建控制器之前设置您的间谍。
示例:
var createController;
beforeEach(inject(function(_$rootScope_, $controller) {
$rootScope = _$rootScope_;
scope = $rootScope.$new();
createController = function() {
$controller('Item as item', {
$scope: scope,
items: []
});
};
}));
it('should open a new item modal', function() {
spyOn(modalService, 'newItemModal').and.callThrough();
createController();
expect(scope.item.newItemModal).toHaveBeenCalled();
});
请注意,您无法监视 scope.item
,因为它在控件创建之前不会被创建,因此您将不得不监视 modalService
。
我正在尝试测试通过 angular 控制器中的局部变量调用服务方法时的场景。
在这种情况下,当项目数组为 0 时,将通过模态服务触发创建新项目模态。
控制器:
(function() {
'use strict';
angular
.module('app')
.controller('Item', Item);
//items is resolved through the ui-router resolve
//items contains a array of item objects. Will be an empty array if there are no items for that user
Item.$inject = ['items', 'modalService'];
function Item(items, modalService) {
var vm = this;
vm.items = items;
vm.newItemModal = modalService.newItemModal;
if (vm.items !== undefined) {
if (vm.items.length === 0) {
vm.newItemModal();
}
}
}
})();
vm.newItemModal() 触发要显示的新项目模式。但是,如何在 jasmine 中测试这种情况?
目前测试:
describe('Controller: Item', function(){
var scope,
ctrl,
items,
modalService,
mockItems = [{ name: 'item1', desc:'desc1'}, { name: 'item2', desc:'desc2'}];
//mocking the modalService
beforeEach(function(){
module(function($provide){
modalService = {
newItemModal: function(){
return;
}
};
$provide.value('modalService', modalService);
});
});
beforeEach(inject(function(_$rootScope_, $controller) {
$rootScope = _$rootScope_;
scope = $rootScope.$new();
ctrl = $controller('Item as item', {
$scope: scope,
items: mockItems
});
}));
it('should verify the vm object', function(){
expect(scope.item.newItemModal).toBeDefined();
expect(scope.item.items).toEqual(mockItems);
});
//Separate test-suite as items is initialised with an empty array
describe('new item modal', function(){
beforeEach(inject(function(_$rootScope_, $controller) {
$rootScope = _$rootScope_;
scope = $rootScope.$new();
ctrl = $controller('Item as item', {
$scope: scope,
items: []
});
it('should open a new item modal', function(){
//returns 0
console.log('Items length', scope.items.length);
spyOn(scope.item, 'newItemModal').and.callThrough();
//testing this assertion fails
expect(scope.item.newItemModal).toHaveBeenCalled();
});
}));
});
});
问题是当下面一行被执行时:
spyOn(scope.item, 'newItemModal').and.callThrough();
控制器已创建,代码已执行。
您需要在创建控制器之前设置您的间谍。
示例:
var createController;
beforeEach(inject(function(_$rootScope_, $controller) {
$rootScope = _$rootScope_;
scope = $rootScope.$new();
createController = function() {
$controller('Item as item', {
$scope: scope,
items: []
});
};
}));
it('should open a new item modal', function() {
spyOn(modalService, 'newItemModal').and.callThrough();
createController();
expect(scope.item.newItemModal).toHaveBeenCalled();
});
请注意,您无法监视 scope.item
,因为它在控件创建之前不会被创建,因此您将不得不监视 modalService
。