Protractor HTTP Mocking
Protractor HTTP Mock provides a NodeJS module designed to facilitate mocking HTTP calls within Protractor end-to-end tests, specifically for AngularJS applications. Its core function is to allow developers to isolate UI and client-side application code by intercepting and responding to network requests with predefined data, thus removing dependencies on external APIs during test execution. A key differentiator is its independence from Angular Mocks (ngMockE2E), meaning it does not require any modifications to the AngularJS application under test. The current stable version, 0.10.0, was released in 2017. Due to its tight coupling with Protractor, which was officially deprecated in 2022, `protractor-http-mock` is effectively an abandoned package with no ongoing development or maintenance.
Common errors
-
TypeError: mock.teardown is not a function
cause The `protractor-http-mock` module was not correctly imported or its `teardown` method was called out of context.fixEnsure you have `const mock = require('protractor-http-mock');` at the top of your test file and call it as `mock.teardown();`. -
HTTP requests are not being mocked (application still makes real network calls).
cause The `mock()` function was called too late, after the browser had already initiated the HTTP requests, or the mock definition itself is incorrect (e.g., wrong path, method, or missing `regex: true` for regex paths).fixCall `mock([...])` within a `beforeEach` block, ensuring it runs before `browser.get()` or any actions that trigger the HTTP requests. Double-check your mock definition's `path`, `method`, `params`, and `queryString` to ensure it precisely matches the outgoing request. Consider adding `regex: true` if using regular expressions in paths. -
Error: Cannot find module 'my-mocks/users'
cause The `protractor-http-mock` configuration for mock file directories (`rootDirectory` or `mocks.dir`) is incorrect, or the specified mock file name does not exist or has a different path.fixVerify that `protractor-http-mock.config.rootDirectory` is set correctly (e.g., `__dirname` of your config file) and that `protractor-http-mock.config.mocks.dir` accurately points to the subdirectory containing your mock files. Ensure the file 'users.js' exists within that directory and exports the mock definition. -
Path '/api/data' with method 'GET' was not mocked
cause The incoming HTTP request did not match any of the currently active mock definitions. This could be due to a mismatch in `path`, `method`, `params`, `queryString`, or `headers`.fixInspect the actual HTTP request made by the browser (via browser developer tools) and compare it against your mock definition. Adjust the mock's `request` properties (path, method, params, queryString, headers, data) to exactly match the observed request. Remember to enable `regex: true` if using regular expressions in the `path`.
Warnings
- breaking The Protractor E2E test framework, on which `protractor-http-mock` is entirely dependent, has been officially deprecated since August 2022 and reached end-of-life on August 31, 2023. This renders `protractor-http-mock` effectively obsolete and unmaintained.
- gotcha Mocks must be configured and called using the `mock()` function *before* the browser navigates or reloads, as `protractor-http-mock` intercepts requests at the network level. If `mock()` is called after `browser.get()` or a page reload, the requests might not be intercepted.
- gotcha Failing to call `mock.teardown()` after each test can lead to mocks persisting across tests, causing unexpected behavior, side effects, and unreliable test results.
- gotcha When using mock files (e.g., `mock(['my-file'])`), incorrect `rootDirectory` or `mocks.dir` configuration in `protractor-http-mock`'s global config will prevent the system from locating the mock files, leading to requests not being intercepted.
- gotcha By default, the `path` property in a mock request object uses exact string matching. To use regular expressions for flexible path matching, you must explicitly set the `regex` property to `true` in the request definition.
Install
-
npm install protractor-http-mock -
yarn add protractor-http-mock -
pnpm add protractor-http-mock
Imports
- mock
import mock from 'protractor-http-mock';
const mock = require('protractor-http-mock'); - mock.config
mock.config = {...}; // if 'mock' was imported via ESM 'import'require('protractor-http-mock').config = { rootDirectory: __dirname, protractorConfig: 'my-protractor-config.conf' }; - mock.teardown
teardown();
mock.teardown();
Quickstart
const mock = require('protractor-http-mock');
const path = require('path');
exports.config = {
directConnect: true,
capabilities: {
'browserName': 'chrome'
},
framework: 'jasmine',
specs: [path.resolve(__dirname, 'mock.spec.js')],
onPrepare: function() {
require('protractor-http-mock').config = {
rootDirectory: __dirname,
protractorConfig: 'protractor.conf.js', // Or the actual name of this config file
mocks: {
default: ['mock-login'],
dir: 'mocks'
}
};
}
};
// mock.spec.js (in the same directory, or specified in specs)
describe('Protractor HTTP Mock Example', function() {
beforeEach(function() {
mock.setup(); // Ensure mocks are cleared and ready for each test
});
afterEach(function() {
mock.teardown();
});
it('should mock a GET request for user data', function() {
mock([
{
request: {
path: '/api/users/1',
method: 'GET'
},
response: {
data: {
userName: 'Mocked User',
email: 'mock@example.com'
},
status: 200
}
}
]);
// Assume your app navigates to a page that makes this request
browser.get('http://localhost:8000/app/#/users/1');
// Example: Verify UI reflects mocked data (replace with actual selectors)
element(by.id('username-display')).getText().then(function(text) {
expect(text).toEqual('Mocked User');
});
element(by.id('email-display')).getText().then(function(text) {
expect(text).toEqual('mock@example.com');
});
});
it('should load mocks from a file', function() {
// Create a file: mocks/products.js
// module.exports = [{ request: { path: '/api/products', method: 'GET' }, response: { data: [{id: 1, name: 'Mock Product'}] } }];
mock(['products']); // Loads from mocks/products.js relative to rootDirectory
browser.get('http://localhost:8000/app/#/products');
// Assert that products are loaded from mock
});
});