I have tried various ways of instantiating the mocked service 'listFilterManager' and passing this to the controller. Although the mocked service is created and accessible, when the scope.$digest() is executed, the actual non-mocked service runs instead of the mocked listFilterManager. Even more confusing is that the resourceStore service is properly mocked and injected. Any help would be greatly appreciated.
Relevant code:
beforeEach(function(){
module('listModule');
module(function($provide){
$provide.factory('resourceStore', function(){
return {
alertsArray: Object.keys(mockData).map(function(key){
return mockData[key];
})
};
});
$provide.value('listFilterManager',{
filterList: jasmine.createSpy('filterList').and.callFake(function(input){
return input;
})
});
});
});
describe('instantiates the Alert List Ctrl', function(){
var scope, listFilterParams, listFilterManager, resourceStore, tableAccessorDictionaries, AlertListCtrl;
beforeEach(function(){
inject(function(_$rootScope_, $controller, _tableAccessorDictionaries_, _listFilterParams_, _resourceStore_, _listFilterManager_){
scope = _$rootScope_.$new();
listFilterParams = _listFilterParams_;
listFilterManager = _listFilterManager_; //this refs the mocked service, but the actual service is the one that is executed.
var deps = {
'$scope': scope,
'tableAccessorDictionaries': _tableAccessorDictionaries_,
'listFilterManager': _listFilterManager_,
'listFilterParams': _listFilterParams_,
'resourceStore': _resourceStore_
};
AlertListCtrl = $controller('AlertListCtrl', deps);
});
});
it('it should filter the list when a list filter parameter changes', function(){
expect(listFilterManager.filterList).not.toHaveBeenCalled();
scope.filterParams.text = 'This is a test query';
scope.$digest();
expect(listFilterManager.filterList).toHaveBeenCalled();
});
});
So you're saying that 'listFilterManager' is a service but in the beforeEach method, you are providing it as a value. You need to provide it as a factory in order for it to be properly mocked. Replace the following
$provide.value('listFilterManager',{
filterList: jasmine.createSpy('filterList').and.callFake(function(input){
return input;
})
});
with:
$provide.factory('listFilterManager', function () {
return {
filterList: jasmine.createSpy('filterList').and.callFake(function(input){
return input;
};
})
});
and it should work properly.
After some time I figured it out. The issue was because the function I was testing was called from within an underscore.debounce wrapper. Debounce apparently causes testing issues, as described here . The solution is to redefine _.debounce within the test file as such (credit to the aforementioned post):
_.debounce = function (func) { return function () { func.apply(this, arguments);}; };
Whew, what a frustrating issue, but hopefully this will help someone else in need!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.