Sunday 15 May 2011

angularjs - Jasmine - Check if service method within a controller method was called -



angularjs - Jasmine - Check if service method within a controller method was called -

i started testing ionic/angularjs app jasmine 1 day ago. i'm not sure if totally missunderstood thought of testing, want test if service method within controller method called , how controller reacts on came back.

my controller function i'd test looks this:

$scope.init = function() { dataservice.fetchvalues('dataprotection').then(function (result) { $scope.dataprotection = result; }, function (failure) { $scope.dataprotection = 'no dataprotection available'; }); };

my test should this:

describe('dataprotectioncontroller', function () { beforeeach(inject(function ($rootscope, $controller, dataservice) { scope = $rootscope.$new(); controller = $controller('dataprotectionctrl', { '$scope': scope }); dataservice = dataservice; })); it('should init dataprotection on startup', function () { // phone call init function in controller scope.init(); //check if dataservice.fetchvalues have been called 'dataprotection' parameter expect(dataservice, 'fetchvalues').tohavebeencalledwith('dataprotection'); //calling fetchvalues should init scope.dataprotection variable expect(scope.dataprotection).tobedefined(); }); });

of course of study not working. errorlogs tell me create spy object. did...

spyon(dataservice, 'fetchvalues').andcallthrough();

didn't help i'm calling

dataservice.fetchvalues('dataprotection');

right after "scope.init();". first expect passes.

the thing don't understand is: why creating spy object dataservice fetchvalues() method , after phone call parameter , after inquire if called given parameter? don't want phone call manually, want check if dataservice.fetchvalues('dataprotection') called within scope.init() function in dataprotectioncontroller.

sorry if stupid question, totally got lost... help!

the next syntaxes jasmine 2.0, if using jasmine 1.3 need create little changes.

first of need inject dataservice controller:

var $scope, dataservice, $q; beforeeach(module('myapp')); beforeeach(inject(function($controller, $rootscope, _dataservice_, _$q_) { $scope = $rootscope.$new(); dataservice = _dataservice_; controller = $controller('dataprotectionctrl', { '$scope': $scope, 'dataservice': dataservice }); $q = _$q_; }));

note if utilize and.callthrough() spy delegate function phone call real fetchvalues implementation, unless have replaced mocked function yourself.

you can instead utilize and.callfake homecoming promise:

spyon(dataservice, 'fetchvalues').and.callfake(function(input) { var deferred = $q.defer(); deferred.resolve('mock'); homecoming deferred.promise; });

otherwise next code in controller wouldn't homecoming anything:

dataservice.fetchvalues('dataprotection')

which means seek next on undefined:

.then(function(result) { ...

when using ngmock need synchronously maintain flow of tests, after calling init need manually trigger digest promise resolve:

$scope.init(); $scope.$digest();

and syntax verifying service function called is:

expect(dataservice.fetchvalues).tohavebeencalledwith('dataprotection');

demo: http://plnkr.co/edit/pslme1ve1m1e6hbm1j6d?p=preview

angularjs testing jasmine ionic-framework

No comments:

Post a Comment