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
Post a Comment