javascript - Angularjs unit testing resolving promises -


i'm doing wrong can't figure out how fix it.

i want test controller uses resource (ngresource) , want use spy test double resource doesn't http call. in code below want test search function in controller.

controller:

controllers = angular.module('app.controllers'); controllers.controller('landingctrl', ['$scope', '$q', 'categoryresource', function ($scope, $q, categoryresource) {      $scope.search = function (text) {         console.log('searching for: ' + text);         var deferred = $q.defer();         categoryresource.query({ searchterm: text }, function (result) {             if (result.length == 0) {                 deferred.resolve(['no results found']);             } else {                 deferred.resolve(result);             }         });         return deferred.promise;     } }]); 

service:

var services = angular.module('app.services');     services.factory('categoryresource', ['$resource', function ($resource) {     var resource = $resource('/api/category');         return resource; }]); 

spec landingctrl:

describe('controller: landingctrl ', function () {      var $q,         $rootscope,         $scope;      beforeeach(module('ngresource'));     beforeeach(module('app.services'));     beforeeach(module('app.controllers'));      beforeeach(inject(function (_$rootscope_, _$q_) {         $q = _$q_;         $rootscope = _$rootscope_;     }));      // mock depencencies, scope. $resource or $http     beforeeach(inject(function ($controller, $injector, categoryresource) {         $scope = $rootscope.$new();          spyon(categoryresource, 'query').andcallfake(function (searchtext) {             console.log('query fake being called');             var deferred = $q.defer();             deferred.resolve(['test', 'testing', 'protester']);             return deferred.promise;         });          landingctrl = $controller('landingctrl', {             '$scope': $scope,             '$q': $q,             'categoryresource': categoryresource         });     }));      aftereach(inject(function ($rootscope) {         $rootscope.$apply();     }));      it('should return words "test" in them"', function () {         $scope.search('test').then(function (results) {             console.log(results);             expect(results).tocontain('test');         });         $scope.$apply();     }); }); 

the test executes without errors passes without ever resolving promise code inside "then" function never gets called. doing wrong?

i've created plunker above , test should fail:

http://plnkr.co/edit/ade6ftajgbdom33rtbzs?p=preview

your spec mocking categoryresource.query() returns promise, controller isn't expecting that. calls query() , passes callback, , within callback thing. in other words, spec isn't testing controller does.

here's fixed spec:

spyon(categoryresource, 'query').andcallfake(function (searchtext, callback) {     console.log('query fake being called');     callback(['test', 'testing', 'protester']); });  ...  it('should return words "test" in them"', function () {     var results;      $scope.search('test').then(function (_results_) {         console.log(results);         results = _results_;     });     $scope.$apply();      expect(results).tocontain('test'); }); 

working plunker

notice have moved expectation outside then() callback, test breaks if promise isn't resolved.


Comments

Popular posts from this blog

Email notification in google apps script -

c++ - Difference between pre and post decrement in recursive function argument -

javascript - IE11 incompatibility with jQuery's 'readonly'? -