javascript - AngularJS Karma Test Spec Promise not resolved and .then() not called -
i have problem angularjs karma unit testing service.
i have service service method this:
service.getintersectingelements = function (element, elements) { var deferred = $q.defer(); var tolerance = 20; var intersectingelements = []; $timeout(function () { (var = 0; < elements.length; i++) { if (element.$$hashkey != elements[i].$$hashkey) if (service.checkintersection(element.location, elements[i].location, tolerance)) intersectingelements.push(elements[i]); } if (intersectingelements.length > 0) deferred.resolve(intersectingelements); else deferred.reject(); }); return deferred.promise; };
it works fine if called controller. want test method, returns promise resolved later. want value resolved , compare in unit test.
so wrote following karma test:
it('should intersecting elements', function () { var element = {id: 1, name: 'water', location: {x: 200, y: 200}}; var elements = [{id: 2, name: 'fire', location: {x: 200, y: 200}}]; service.getintersectingelements(element, elements).then(function (result) { expect(result).toequal([{id: 2, name: 'fire', location: {x: 200, y: 200}}]); }); });
i call service method same in controller. test ends done ok. if change line
expect(result).toequal([{id: 2, name: 'fire', location: {x: 200, y: 200}}]);
to
expect(result).toequal("test");
the test done , not failing. in case expect test fail.
i tried injecting $rootscope
, calling $rootscope.$digest();
after service method call. should resolve previous promise, in fact did not take effect, if place digest or not...
so question is, how test promise returned service method , compare value resolved , passed then() of promise in karma unit test.
edit: i've tried $timeout.flush();
, $rootscope.$digest();
after service method call.
i injected services if helps:
var service; var $timeout; var $rootscope; beforeeach(module('app')); beforeeach(module('app.services')); beforeeach(angular.mock.inject(function (intersectservice, _$timeout_, _$rootscope_) { service = intersectservice; $timeout = _$timeout_; $rootscope = _$rootscope_; }));
ok fixed myself...
first... need flush timeout (which tried earlier) , need scope apply
it('should intersecting elements', function () { var element = {id: 1, name: 'water', location: {x: 200, y: 200}, $$hashkey: "1"}; var elements = [ {id: 1, name: 'water', location: {x: 200, y: 200}, $$hashkey: "1"}, {id: 2, name: 'fire', location: {x: 200, y: 200}, $$hashkey: "2"} ]; var promise = service.getintersectingelements(element, elements); var result; promise.then(function (res) { result = res; }, function (error) { result = "error"; }); $rootscope.$apply(); $timeout.flush(); expect(result).toequal([{id: 2, name: 'fire', location: {x: 250, y: 200}, $$hashkey: "2"}]); });
the whole thing looks above.
but second... that's not true mistake. used $$hashkey
property in service method (see above in question), (obviously) not set, because did not set in test data. $$hashkey
exists if variable on $scope
. didn't remember set it.
so answer set $$hashkey
seen in code above.
Comments
Post a Comment