Reputation: 522
I grabbed a snippet of code to mock local storage, however, when I ran the test, it threw this error. As it says, it can't find the getItem method, but I explicitly declared the method outside the beforeEach block. I don't know what's throwing this error - would appreciate tips and suggestions!
Here are my files:
mainCtrl.spec.js
describe('Controller: MainCtrl', function () {
var store = {};
var ls = function() {
return JSON.parse(store.storage);
};
var localStorage = {};
var getItem = function(key) {
return store[key];
}
var setItem = function(key, value) {
store[key] = value;
}
beforeEach(function() {
// setUp.
module('mytodoApp');
// LocalStorage mock.
spyOn(localStorage, 'getItem').andCallFake(getItem); <-- throwing the error
Object.defineProperty(sessionStorage, "setItem", { writable: true });
spyOn(localStorage, 'setItem').andCallFake(setItem);
});
afterEach(function() {
store = {};
});
var MainCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
MainCtrl = $controller('MainCtrl', {
$scope: scope
});
}));
it('should have no items to start with', function() {
// expect(scope.todos.length).toBe(0);
expect(Object.keys(store).length).toBe(0);
});
});
mainCtrl.js
angular.module('mytodoApp')
.controller('MainCtrl', function ($scope, localStorageService) {
// breaks on repeat or blank input
function addTodoFn() {
$scope.todos.push($scope.todo);
$scope.todo = '';
}
function removeTodoFn(index) {
$scope.todos.splice(index, 1);
}
function watchFn() {
localStorageService.set('todos', $scope.todos);
}
//////////
var todosInStore = localStorageService.get('todos');
$scope.todos = todosInStore || [];
$scope.$watch('todos', watchFn, true);
$scope.addTodo = addTodoFn;
$scope.removeTodo = removeTodoFn;
});
EDIT
var localStorage = {
getItem: function(key) {
return store[key];
},
setItem: function(key, value) {
store[key] = value;
}
};
beforeEach(function() {
// setUp.
module('mytodoApp');
// LocalStorage mock.
spyOn(localStorage, 'getItem').andCallFake(getItem);
Object.defineProperty(sessionStorage, 'setItem', { writable: true });
spyOn(localStorage, 'setItem').andCallFake(setItem);
});
I changed it as per @CosmicChild's suggestion to no avail.
New error message
ReferenceError: Can't find variable: getItem
Upvotes: 0
Views: 653
Reputation: 181
You need to define an empty method inside the localStorage object that you are stubbing,
var localStorage = {
getItem: function(key) {
},
setItem: function(key, value) {
}
};
Upvotes: 1
Reputation: 522
As it turns out, it's just a simple syntax error. Taking another look at the Jasmine docs helped (maybe it's to do with the version of Jasmine you're using, but this is the wrong syntax in version 2.3).
beforeEach(function() {
// setUp.
module('mytodoApp');
// LocalStorage mock.
spyOn(localStorage, 'getItem').and.callFake(getItem); <-- .and.callFake
Object.defineProperty(sessionStorage, 'setItem', { writable: true });
spyOn(localStorage, 'setItem').and.callFake(setItem);
});
Upvotes: 0