javascript - How do I mock the result in a $http.get promise when testing my AngularJS controller? -


after reading, seems recommended way call web service angularjs controller use factory , return promise that.

here have simple factory calls sample api.

myapp.factory('myfactory', ['$http',function($http) { var people = {         requestpeople: function(x) {             var url = 'js/test.json';             return $http.get(url);         }     }; return people; }]); 

and how call in controller

myapp.controller('myctrl1', ['$scope', 'myfactory', function ($scope, myfactory) {         myfactory.requestpeople(22).then(function(result) {              $scope.peoplelist = result;         }); }]); 

while works fine, able mock result passed in when then called. possible?

my attempt far has produced nothing. attempt:

//fake service var mockservice = {     requestpeople: function () {         return {             then: function () {                 return {"one":"three"};             }         }      } };   //some setup beforeeach(module('myapp.controllers')); var ctrl, scope;  beforeeach(inject(function ($rootscope, $controller) {     scope = $rootscope.$new();      ctrl = $controller('myctrl1', { $scope: scope, myfactory: mockservice }); }));  //test it('event types empty should default false', inject(function () {     expect(scope.peoplelist.one).tobe('three'); })); 

the error when running in karma runner, is

typeerror: 'undefined' not object (evaluating 'scope.peoplelist.one')

how can test working mocked data?

i don't think $httpbackend you're after here, want whole factory mocked without having dependency on $http?

take @ $q, in particular code sample under testing header. issue might resolved code looks this:

'use strict';  describe('mocking factory response', function () {      beforeeach(module('myapp.controllers'));      var scope, fakefactory, controller, q, deferred;      //prepare fake factory     beforeeach(function () {         fakefactory = {             requestpeople: function () {                 deferred = q.defer();                 // place fake return object here                 deferred.resolve({ "one": "three" });                 return deferred.promise;             }         };         spyon(fakefactory, 'requestpeople').andcallthrough();     });      //inject fake factory controller     beforeeach(inject(function ($rootscope, $controller, $q) {         scope = $rootscope.$new();         q = $q;         controller = $controller('myctrl1', { $scope: scope, myfactory: fakefactory });     }));      it('the peoplelist object not defined yet', function () {         // before $apply called promise hasn't resolved         expect(scope.peoplelist).not.tobedefined();     });      it('applying scope causes defined', function () {         // propagates changes models         // happens when you're on web page, not in unit test framework         scope.$apply();         expect(scope.peoplelist).tobedefined();     });      it('ensure method invoked', function () {         scope.$apply();         expect(fakefactory.requestpeople).tohavebeencalled();     });      it('check value returned', function () {         scope.$apply();         expect(scope.peoplelist).tobe({ "one": "three" });     }); }); 

i've added tests around $apply does, didn't know until started playing this!

gog


Comments

Popular posts from this blog

javascript - DIV "hiding" when changing dropdown value -

Does Firefox offer AppleScript support to get URL of windows? -

android - How to install packaged app on Firefox for mobile? -