Reputation: 6531
I've begun using jasmine to test my controllers in angularjs however after reading some tutorials I am a bit stuck.
I have this simple angularjs controller called jasmineController
(function () {
"use strict";
var myAppModule = angular.module('myApp');
myAppModule.controller('jasmineController', ['$scope', 'genericService',
function ($scope, genericService) {
$scope.name = 'Superhero';
$scope.counter = 0;
$scope.$watch('name', function (newValue, oldValue) {
$scope.counter = $scope.counter + 1;
});
$scope.testPromise = function() {
return genericService.getAll("dashboard", "currentnews", null, null, null);
}
$scope.getNewsItems = function () {
genericService.getAll("dashboard", "currentnews", null, null, null).then(function (data) {
$scope.name = 'Superhero';
$scope.newsItems = data;
});
}
}
]);
})();
In my jasmine test I wanted to call getNewsItems and check that it can call genericService.getAll and that $scope.newsItems is assigned some data. I understand that I would be mocking out the service and I won't actually call it.
Here is my spec
describe("test", function () {
// Declare some variables required for my test
var controller, scope, genericService;
// load in module
beforeEach(module("myApp"));
beforeEach(inject(function ($rootScope, $controller, _genericService_) {
genericService = _genericService_;
// assign new scope to variable
scope = $rootScope.$new();
controller = $controller('jasmineController', {
'$scope': scope
});
}));
it('sets the name', function () {
expect(scope.name).toBe('Superhero');
});
it('should assign data to scope', function() {
//var fakeHttpPromise = {success: function () { }};
scope.getNewsItems();
spyOn(genericService, 'getAll');
expect(genericService.getAll).toHaveBeenCalledWith('dashboard', 'currentnews');
});
});
I've got a spyon for genericService.getall() but apart from that I am a bit stuck with checking that my scope variable is assigned a value.
I also get this stack trace:
Error: Expected spy getAll to have been called with [ 'dashboard', 'currentnews' ] but it was never called.
at stack (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:1441:11)
at buildExpectationResult (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:1408:5)
at expectationResultFactory (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:533:11)
at Spec.prototype.addExpectationResult (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:293:5)
at addExpectationResult (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:477:9)
at Anonymous function (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:1365:7)
at Anonymous function (file:///C:/Projects/2013/AMT2015/AMT2015.WebAPP/Scripts/tests/controllers/dashboardControllerSpec.js:49:9)
at attemptSync (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:1759:9)
at QueueRunner.prototype.run (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:1747:9)
at QueueRunner.prototype.execute (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:1733:5)
Upvotes: 1
Views: 856
Reputation: 6531
I ended up doing this:
describe("test", function () {
// Declare some variables required for my test
var controller, scope, genericService;
// load in module
beforeEach(module("myApp"));
beforeEach(inject(function ($rootScope, $controller, _$q_, _genericService_) {
genericService = _genericService_;
var deferred = _$q_.defer();
deferred.resolve('resolveData');
spyOn(genericService, 'getAll').and.returnValue(deferred.promise);
scope = $rootScope.$new();
controller = $controller('jasmineController', {
'$scope': scope
});
}));
it('sets the name', function () {
expect(scope.name).toBe('Superhero');
});
it('should assign data to scope', function() {
//spyOn(genericService, 'getAll').and.callFake(function() {
//});
scope.getNewsItems();
scope.$apply();
expect(scope.newsItems).toBe('resolveData');
//expect(genericService.getAll).toHaveBeenCalledWith('dashboard', 'currentnews', null, null, null);
});
});
Because my test is more than just calling a service but handling a promise as well I had to inject $q. Then with spy on I say to call service and method and the return value is the deferred promise.
Finally I can look at the scope variable to see if anything is assigned with this line:
expect(scope.newsItems).toBe('resolveData');
Thanks to everyone that helped.
Upvotes: 1
Reputation: 3240
You need to put the spy first before calling the test function. And you are you actually passing more parameters to the service function. So you need to test with the exact parameter list.
it('should assign data to scope', function() {
//var fakeHttpPromise = {success: function () { }};
spyOn(genericService, 'getAll');
scope.getNewsItems();
expect(genericService.getAll).toHaveBeenCalledWith('dashboard', 'currentnews',null,null,null);
});
Upvotes: 1