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?
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.
AngularJS also provides the ngMock module, which provides mocking for your tests. This is used to inject and mock AngularJS services within unit tests.
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.
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 }); }));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With