Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test with Jasmine an AngularJS controller that calls service method that returns promise

Tags:

I am using v1.2.0-rc.3 of AngularJS with Jasmine test framework.

I am trying to assert that a controller calls a service method. The service method returns a promise. The controller looks like this:

angular.module('test', []) .controller('ctrl', ['$scope', 'svc', function ($scope, svc) {   $scope.data = [];   svc.query()   .then(function (data) {     $scope.data = data;   }); }]); 

I want to test that data is assigned to the scope when the service method's deferred is resolved. I have created a mock for the service and the unit test looks like this:

describe('ctrl', function () {   var ctrl, scope, svc, def, data = [{name: 'test'}];   beforeEach(module('test'));   beforeEach(inject(function($controller, $rootScope, $q) {     svc = {       query: function () {         def = $q.defer();         return def.promise;       }     };     scope = $rootScope.$new();     controller = $controller('ctrl', {       $scope: scope,       svc: svc     });   }));   it('should assign data to scope', function () {     spyOn(svc, 'query').andCallThrough();     deferred.resolve(data);     scope.$digest();     expect(svc.query).toHaveBeenCalled();     expect(scope.data).toBe(data);   }); }); 

I expect the query method of svc to be called, but apparently it hasn't.

I followed this guide to mocking promises in unit tests.

What am I doing wrong?

like image 253
gwhn Avatar asked Oct 24 '13 10:10

gwhn


People also ask

How to test Directive AngularJS?

If a directive creates its own scope and you want to test against it, you can get access to that directive's scope by doing var directiveScope = myElement. children(). scope() - It will get the element's child (the directive itself), and get the scope for that.

Which component is used to inject and mock AngularJS service within the unit test?

AngularJS also provides the ngMock module, which provides mocking for your tests. This is used to inject and mock AngularJS services within unit tests.

How to do unit testing in Angular js?

Testing in AngularJS is achieved by using the karma framework, a framework which has been developed by Google itself. The karma framework is installed using the node package manager. The key modules which are required to be installed for basic testing are karma, karma-chrome-launcher ,karma-jasmine, and karma-cli.


1 Answers

It seems I was placing my spy in the wrong place. When I place it in the beforeEach, the test passes.

  beforeEach(inject(function($controller, $rootScope, $q) {     svc = {       query: function () {         def = $q.defer();         return def.promise;       }     };     spyOn(svc, 'query').andCallThrough();     scope = $rootScope.$new();     controller = $controller('ctrl', {       $scope: scope,       svc: svc     });   })); 
like image 104
gwhn Avatar answered Sep 19 '22 00:09

gwhn