angularjs - How to switch between httpBackendMocks in protractor test -


i trying mock responses api calls within protractor tests. in different tests (and within tests), application post api (always same url) different data posted, , expecting different responses.

specifically, search engine, , sending different queries , expecting different results back. have working code below, getting unmanageable:

var httpbackendmock = function() {   angular.module('httpbackendmock', ['ngmocke2e'])     .run(function($httpbackend) {       $httpbackend.whenpost('//search_endpoint').respond(function(method, url, query, headers) {         query = json.parse(query);         if (query.bla = 'foo') {           var results = {... lots of json ...};         } else if (query.bla = 'bar') {           var results = {... lots of json ...};         } else if (query.something.else != 'whatever') {           var results = {... lots of json ...};         ... etc ...         } else {           var results = {... lots of json ...};         }         return [200, results];       });       $httpbackend.whenget(/.*/).passthrough();     }) };  beforeeach(function(){   browser.addmockmodule('httpbackendmock', httpbackendmock); }); 

what i'd have each possible response in separate mock, remove beforeeach , add mocks when needed, so:

it('paginates', function(){   // mocking search 13 results, showing 10 results per page   browser.addmockmodule('search_results', <some function>);   $('#searchbox').sendkeys('some keyword search');   $('#searchbutton').click();   expect($('#results li').count()).toequal(10);   browser.clearmockmodules();   browser.addmockmodule('search_results_page2', <some other function>);   $('#next').click();   expect($('#results li').count()).toequal(3) }); 

there 2 problems this.

1) doesn't work. after clearing , adding second mock, getregisteredmockmodules() shows second mock, seems first mock still getting used, based on expects , manual inspection when using browser.pause() chromedriver. seems can't change mocks without @ least reloading page.

2) if did work, there huge amount of repeated code each mock module, has set everything, including passthrough().

what better if pass desired response mock adding, tried , passed own function isn't available within angular.module scope. way think of create angular module provider had single variable keep track of response desired, , inject mocked module. haven't tried yet seems unnecessarily complex solution.

a mock-module in protractor code gets executed browser upon each full-page-refresh. it's mechanism save hassle of doing yourself, since such refresh cleans state of browser (with exception of cookies of course). found out, until trigger such refresh (with browser.get()), modules never executed. can manually browser.executescript() if want.

regarding mess ensues mocking back-end - took following approach: have default mock implementation back-end while making overridable , registering before each test init function:

mocked-backend-base.js

exports.httpbackendmockbase = function () {     var exposebackendcalls = function ($httpbackend) {         this.getloginauthenticated = $httpbackend.whenget(/login\/authenticated.*/);         this.getfindstuff = $httpbackend.whenget(/lookup\/findstuff.*/);         this.getfullprofile = $httpbackend.whenget(/api\/full.*/);     };      angular.module('httpbackendmockbase', ['myclientapp', 'ngmocke2e'])     .service('httpbackendmockbase', exposebackendcalls)     .run(function (httpbackendmockbase, testfixture) {         httpbackendmockbase.getloginauthenticated.respond(function () {             return [200, null, {}];         });         httpbackendmockbase.getfindstuff.respond(function () {             return [200, { stuff: testfixture.stuff }, {}];         });         httpbackendmockbase.getfullprofile.respond(function () {             return [200, { profile: testfixture.fullprofile }, {}];         });     }); }; 

if need parts of overridden @ point register new mock module. remove in aftereach block:

mocked-backend-special-user.js

exports.httpbackendmock = function() {     angular.module('httpbackendmockspecialuser', []).run(function (httpbackendmockbase, testfixture) {         httpbackendmockbase.getloginauthenticated.respond(function() {             return [200, testfixture.specialuser, {}];         });     }); }; 

the testfixture module holds our data , registered before mocked-backend-base:

fixture.js

exports.data = {     stuff: null,     fullprofile: {},     specialuser: {} };  exports.module = function (data) {     angular.module('backendfixture', []).constant('testfixture', data); }; 

the init function:

var fixturemodule = require('fixture'); var basemockedbackend = require('mocked-backend-base');  browser.addmockmodule('backendfixture', fixturemodule.module, fixturemodule.data); browser.addmockmodule('httpbackendmockbase', basemockedbackend.httpbackendmockbase); 

Comments

Popular posts from this blog

javascript - AngularJS custom datepicker directive -

javascript - jQuery date picker - Disable dates after the selection from the first date picker -