I am trying to mock responses to API calls within Protractor tests. In different tests (and within tests), the application will POST to an API (always the same URL) with dif
A mock-module in protractor is basically code that gets executed into the browser upon each full-page-refresh. It's a mechanism to save you the hassle of doing that yourself, since such a refresh cleans the state of the browser completely (with the exception of cookies of course). As you already found out, until you trigger such a refresh (with browser.get()
), your modules are never executed. You can do that manually with browser.executeScript()
if you want.
Regarding the mess that ensues from mocking your back-end - I took the following approach: Have a default mock implementation for your back-end while making it easily overridable and registering it before each test with an 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 you need parts of it overridden at some point register a new mock module. Remove it in your 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
is from another module that holds our data and is registered before the 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);