Reputation: 213
I am still very new to unit testing, and to be honest, there isn't anything that I could even think of testing, but I cannot build my app unless I have at least 1 test case, so I attempted to make the most simple test case I could, on the smallest block of code in the controller, and it doesn't seem to be working.
I believe it's an error in my test case, and not in my controller's code itself, because when I view my app in the browser with grunt serve
the console shows no errors.
This is the error it gives me:
PhantomJS 2.1.1 (Linux 0.0.0) Controller: MainCtrl should attach a list of jackpot to the scope FAILED
/home/elli0t/Documents/Yeoman Projects/monopoly/app/bower_components/angular/angular.js:3746:53
forEach@[native code]
forEach@/home/elli0t/Documents/Yeoman Projects/monopoly/app/bower_components/angular/angular.js:323:18
loadModules@/home/elli0t/Documents/Yeoman Projects/monopoly/app/bower_components/angular/angular.js:3711:12
createInjector@/home/elli0t/Documents/Yeoman Projects/monopoly/app/bower_components/angular/angular.js:3651:22
workFn@/home/elli0t/Documents/Yeoman Projects/monopoly/app/bower_components/angular-mocks/angular-mocks.js:2138:60
TypeError: undefined is not an object (evaluating 'scope.jackpot') in /home/elli0t/Documents/Yeoman Projects/monopoly/test/spec/controllers/main.js (line 20)
/home/elli0t/Documents/Yeoman Projects/monopoly/test/spec/controllers/main.js:20:17
PhantomJS 2.1.1 (Linux 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.04 secs / 0.007 secs)
This is my test case:
it('should attach a list of jackpot to the scope', function () {
expect(scope.jackpot.length).toBe(2);
});
And this is the block of code I'm attempting to run the test on:
var countInJackpot = localStorageService.get('jackpot');
$scope.jackpot = countInJackpot || [
{
letter: '$',
prize: '$1,000,000 Cash',
numbers: ['$611A','$612B','$613C','$614D','$615E','$616F','$617G','$618F'],
count: [0,0,0,0,0,0,0,0]
},
{
letter: '?',
prize: '$500,000 Vacation Home',
numbers: ['?619A','?620B','?621C','?622D','?632E','?624F','?625G','?626H'],
count: [0,0,0,0,0,0,0,0]
}
];
For the time being, I really just want to write 1 simple test case, so it will let me build the app. I'm currently studying unit testing, but I still don't feel ready to write more complex test cases on my own. I will save that for later.
I have included the entire contents of the files in a gist for reference, if needed, and I can include the contents of the karma.conf.js if necessary.
Upvotes: 2
Views: 4282
Reputation: 165059
I would expect you'd want to test both cases of the localStorageService
having and not having data. To do so, create a spy for localStorageService
(see Spies) and write your tests like this...
'use strict';
describe('Controller: MainCtrl', function () {
var scope, localStorageService, localData;
beforeEach(function() {
localData = {};
module('monopolyApp');
localStorageService = jasmine.createSpyObj('localStorageService', ['get', 'set']);
localStorageService.get.and.callFake(function(key) {
return localData[key];
});
inject(function($rootScope) {
scope = $rootScope.$new();
});
});
it('assigns jackpots from local storage if present', inject(function($controller) {
localData.jackpot = 'whatever, does not matter';
$controller('MainCtrl', {
$scope: scope,
localStorageService: localStorageService
});
expect(localStorageService.get).toHaveBeenCalledWith('jackpot');
expect(scope.jackpot).toBe(localData.jackpot);
}));
it('assigns jackpots from default array if none present in local storage', inject(function($controller) {
$controller('MainCtrl', {
$scope: scope,
localStorageService: localStorageService
});
expect(localStorageService.get).toHaveBeenCalledWith('jackpot');
expect(scope.jackpot.length).toEqual(2);
// maybe include some other checks like
expect(scope.jackpot[0].letter).toEqual('$');
expect(scope.jackpot[1].letter).toEqual('?');
}));
});
Upvotes: 1
Reputation: 1753
Within your test case, scope should be $scope?
OR
You probably haven't setup your testing environment to load in your controller.
Here is an example of mine on testing a controller... Angular makes the setup a little iffy to learn, But once you understand the flow. It's pretty great :)
I'm going to try and add as many comments to explain each piece as I can... but let me know if your need clarification. You might be using jasmine, but keep in mind, this is mocha, im using the angular mock library loaded in via the karma.conf.
describe('myController', function() {
var $scope,
createController;
// Runs before each test. Re-extantiating the controller we want to test.
beforeEach(inject(function($injector) {
// Get hold of a scope (i.e. the root scope)
$scope = $injector.get('$rootScope');
// The $controller service is used to create instances of controllers
var $controller = $injector.get('$controller');
createController = function() {
// Creates the controller instance of our controller.
// We are injecting $scope so we will have access to it
// after the controllers code runs
return $controller('myCtrl', {
'$scope': $scope
});
};
}));
describe('#myFunction', function() {
it('jackpot should contain two objects', function() {
expect($scope.jackpot.length).to.equal(2);
});
});
});
Hope that helped. Here's some of the resources I used to learn :) Good Luck!
Upvotes: 1