AngularJS testing w/ jasmine and $httpBackend -
i'm experimenting angular , want able run automated tests jasmine. i'm having trouble setting test environment. have controllers & services separated separate files
app.js
(function (ng) { 'use strict'; ng.module('demo', ['marvel', 'ngroute']); }(window.angular));
controllers.js
(function (app) { 'use strict'; function paging(pageindex, pagesize, total) { var url = '/characters/' , last = math.floor(total / pagesize); this.first = pageindex === 0 ? null : url + '0'; this.previous = pageindex === 0 ? null : url + (pageindex - 1).tostring(); this.next = last <= pageindex ? null : url + (pageindex + 1); this.last = last <= pageindex ? null : url + last; }; app.controller('characterscontroller', function ($scope, $routeparams, marvelrepository) { var pageindex = parseint($routeparams.pageindex); marvelrepository.fetch(pageindex).then(function (data) { $scope.characters = data.results; $scope.paging = new paging(pageindex, data.limit, data.total); }); }); app.controller('charactercontroller', function ($scope, $window, $routeparams, marvelrepository) { var characterid = $routeparams.id; $scope.back = function () { $window.history.back(); }; marvelrepository.get(characterid).then(function (character) { $scope.character = character; }); }); }(window.angular.module('demo')));
marvel.js
(function (ng, crypto, date) { 'use strict'; var marvel = ng.module('marvel', ['ngresource']); marvel.constant('marvelapikey', { 'public': '**public**' , 'private': '**private**' }); marvel.provider('hash', function (marvelapikey) { var _override = null; function authentication () { this.authenticate = function () { var timestamp = date.now().tostring() , md5hash = crypto.md5(timestamp + marvelapikey.private + marvelapikey.public).tostring(); return { apikey: marvelapikey.public , ts: timestamp , hash: md5hash }; }; } this.override = function (authentication) { _override = function () { return authentication; }; }; this.$get = function () { return _override || new authentication(); } }); marvel.service('marvelrepository', function (hash, $resource) { return { get: function (characterid) { var authentication = hash.authenticate(); return $resource('http://gateway.marvel.com/v1/public/characters/' + characterid, authentication) .get() .$promise .then(function (response) { if (response.code !== 200) { throw response; } return response.data.results[0]; }); }, fetch: function (pageindex) { var authentication = hash.authenticate(); var args = ng.extend({limit:20, offset: pageindex*20}, authentication); return $resource('http://gateway.marvel.com/v1/public/characters', args) .get() .$promise .then(function (response) { if (response.code !== 200) { throw response; } return response.data; }); } }; }); }(window.angular, cryptojs, date));
what write automated test stubs out $httpbackend, uses other components. want override hashprovider values fake own easier testing. here have far.
describe("marvel tests", function () { beforeeach(function () { module('marvel', ['hashprovider', function (hashprovider) { hashprovider.override({ apikey: '123' , ts: '20140601073322' , hash: 'abc123' }); }]); module('demo'); }); it('should able page of characters', inject(function ($controller, $httpbackend) { var scope = {}; $httpbackend.when('get', 'http://gateway.marvel.com/v1/public/characters?apikey=123&ts=20140601073322&hash=abc123&limit=20&offset=20').respond(200, "{data: { results: new array(20), offset: 2, limit 20, total: 100 } }"); $controller('characterscontroller', {$scope: scope, $routeparams: { pageindex: 1 }}); $httpbackend.flush(); expect(scope.characters.length).equal(20); expect(scope.paging.total).equal(100); })); });
however i'm getting following error
marvel tests should able page of characters. typeerror: undefined not function typeerror: undefined not function @ object.fetch (http://localhost:1236/js/marvel.js:55:43) @ new <anonymous> (http://localhost:1236/js/controllers.js:25:26) @ invoke (http://localhost:1236/js/angular/angular.js:4009:17) @ object.instantiate (http://localhost:1236/js/angular/angular.js:4020:23) @ http://localhost:1236/js/angular/angular.js:7312:28 @ null.<anonymous> (http://localhost:1236/tests/tests.js:30:9) @ object.invoke (http://localhost:1236/js/angular/angular.js:4009:17) @ workfn (http://localhost:1236/tests/angular-mock.js:2181:30) @ jasmine.block.execute (http://localhost:1236/tests/jasmine.js:1064:17) @ jasmine.queue.next_ (http://localhost:1236/tests/jasmine.js:2096:31) error: declaration location @ window.inject.angular.mock.inject (http://localhost:1236/tests/angular-mock.js:2152:29) @ null.<anonymous> (http://localhost:1236/tests/tests.js:25:54) @ jasmine.env.describe (http://localhost:1236/tests/jasmine.js:819:21) @ describe (http://localhost:1236/tests/jasmine.js:603:27) @ http://localhost:1236/tests/tests.js:11:1
what missing run end-to-end test using $httpbackend?
maybe it's because registering service under name marvelrepository
, trying inject service named $marvelrepository
.
another error come accross trying config provider of service named hashprovider
this:
.config(function (hashprovider) {...})
but, configuring service need inject provider, in case of hashprovider
wil hashproviderprovider
.
update:
the problem updated code hard determine without ability reproduce, based on stack-trace seems angular might not have been initialized.
this might due how call inject 2nd argument of it()
function, instead of this:
it('should able page of characters', function () { inject(function ($controller, $httpbackend) { var scope = {}; ...
btw, not sure syntax work exected:
module('marvel', ['hashprovider', function (hashprovider) {...}])
(just saying...)
Comments
Post a Comment