jest-mock-axios
Version:
Axios mock for Jest
370 lines (364 loc) • 10.5 kB
JavaScript
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
// lib/mock-axios.ts
import { jest } from "@jest/globals";
import { SynchronousPromise } from "synchronous-promise";
// lib/cancel/Cancel.ts
var Cancel = class {
constructor(message = "Cancel") {
this.message = message;
}
toString() {
return this.message;
}
};
Cancel.prototype.__CANCEL__ = true;
var Cancel_default = Cancel;
// lib/cancel/CancelToken.ts
var CancelToken = class _CancelToken {
static source() {
let cancel;
const token = new _CancelToken((c) => cancel = c);
return {
cancel,
token
};
}
constructor(executor) {
const token = this;
this.promise = new Promise((resolve) => {
token.resolvePromise = resolve;
});
executor(function cancel(message) {
if (token.reason || !token.resolvePromise) {
return;
}
token.reason = new Cancel(message);
token.resolvePromise(token.reason);
});
}
throwIfRequested() {
if (this.reason) {
throw this.reason;
}
}
};
// lib/mock-axios.ts
var _pending_requests = [];
var _responseInterceptors = [];
var _requestInterceptors = [];
var _requestHandler;
var processInterceptors = (data, stack, type) => {
return stack.map(({ [type]: interceptor }) => interceptor).filter((interceptor) => !!interceptor).reduce((_result, next) => {
return next(_result);
}, data);
};
var _newReq = (config = {}, actualConfig = {}) => {
if (typeof config === "string") {
actualConfig.url = config;
config = actualConfig;
}
const method = config.method || "get";
const url = config.url;
const data = config.data;
const promise = SynchronousPromise.unresolved();
if (config.cancelToken) {
config.cancelToken.promise.then((cancel) => {
if (_pending_requests.find((x) => x.promise === promise)) {
MockAxios.mockError(cancel, promise);
}
});
}
const requestConfig = processInterceptors({
config,
data,
method,
promise,
url
}, _requestInterceptors, "onFulfilled");
_pending_requests.push(requestConfig);
if (typeof _requestHandler === "function") {
_requestHandler(requestConfig);
}
return promise;
};
var _helperReq = (method, url, data, config) => {
const conf = data && config ? config : {};
return _newReq(__spreadProps(__spreadValues({}, conf), {
data,
method,
url
}));
};
var _helperReqNoData = (method, url, config) => {
return _helperReq(method, url, {}, config);
};
var MockAxios = jest.fn(_newReq);
MockAxios.get = jest.fn(_helperReqNoData.bind(null, "get"));
MockAxios.post = jest.fn(_helperReq.bind(null, "post"));
MockAxios.put = jest.fn(_helperReq.bind(null, "put"));
MockAxios.patch = jest.fn(_helperReq.bind(null, "patch"));
MockAxios.delete = jest.fn(_helperReqNoData.bind(null, "delete"));
MockAxios.request = jest.fn(_newReq);
MockAxios.all = jest.fn((values) => Promise.all(values));
MockAxios.head = jest.fn(_helperReqNoData.bind(null, "head"));
MockAxios.options = jest.fn(_helperReqNoData.bind(null, "options"));
MockAxios.create = jest.fn(() => MockAxios);
MockAxios.interceptors = {
request: {
// @ts-ignore
use: jest.fn((onFulfilled, onRejected) => {
return _requestInterceptors.push({ onFulfilled, onRejected });
}),
// @ts-ignore
eject: jest.fn((position) => {
_requestInterceptors.splice(position - 1, 1);
}),
// @ts-ignore
clear: jest.fn(() => {
_requestInterceptors.length = 0;
})
},
response: {
// @ts-ignore
use: jest.fn((onFulfilled, onRejected) => {
return _responseInterceptors.push({ onFulfilled, onRejected });
}),
// @ts-ignore
eject: jest.fn((position) => {
_responseInterceptors.splice(position - 1, 1);
}),
// @ts-ignore
clear: jest.fn(() => {
_responseInterceptors.length = 0;
})
}
};
MockAxios.defaults = {
headers: {
common: [],
get: {},
post: {},
delete: {},
put: {},
patch: {},
head: {}
}
};
MockAxios.popPromise = (promise) => {
if (promise) {
for (let ix = 0; ix < _pending_requests.length; ix++) {
const req = _pending_requests[ix];
if (req.promise === promise) {
_pending_requests.splice(ix, 1);
return req.promise;
}
}
} else {
const req = _pending_requests.shift();
return req ? req.promise : void 0;
}
};
MockAxios.popRequest = (request) => {
if (request) {
const ix = _pending_requests.indexOf(request);
if (ix === -1) {
return void 0;
}
_pending_requests.splice(ix, 1);
return request;
} else {
return _pending_requests.shift();
}
};
var popQueueItem = (queueItem = null) => {
const request = MockAxios.popRequest(
queueItem
);
if (request) {
return request.promise;
} else {
return MockAxios.popPromise(queueItem);
}
};
MockAxios.mockResponse = (response, queueItem = null, silentMode = false) => {
response = Object.assign(
{
config: {},
data: {},
headers: {},
status: 200,
statusText: "OK"
},
response
);
let promise = popQueueItem(queueItem);
if (!promise && !silentMode) {
throw new Error("No request to respond to!");
} else if (!promise) {
return;
}
for (const interceptor of _responseInterceptors) {
promise = promise.then(interceptor.onFulfilled, interceptor.onRejected);
}
promise.resolve(response);
};
MockAxios.mockResponseFor = (criteria, response, silentMode = false) => {
if (typeof criteria === "string") {
criteria = { url: criteria };
}
const queueItem = MockAxios.getReqMatching(criteria);
if (!queueItem && !silentMode) {
throw new Error("No request to respond to!");
} else if (!queueItem) {
return;
}
MockAxios.mockResponse(response, queueItem, silentMode);
};
MockAxios.mockError = (error = {}, queueItem = null, silentMode = false) => {
let promise = popQueueItem(queueItem);
if (!promise && !silentMode) {
throw new Error("No request to respond to!");
} else if (!promise) {
return;
}
if (error && typeof error === "object" && error.isAxiosError === void 0) {
error.isAxiosError = true;
}
for (const interceptor of _responseInterceptors) {
promise = promise.then(interceptor.onFulfilled, interceptor.onRejected);
;
}
promise.reject(error);
};
MockAxios.isAxiosError = (payload) => typeof payload === "object" && payload.isAxiosError === true;
MockAxios.lastReqGet = () => {
return _pending_requests[_pending_requests.length - 1];
};
MockAxios.lastPromiseGet = () => {
const req = MockAxios.lastReqGet();
return req ? req.promise : void 0;
};
var _findReqByPredicate = (predicate) => {
return _pending_requests.slice().reverse().find(predicate);
};
var deepEqual = (x, y) => {
if (x === null || x === void 0 || y === null || y === void 0) {
return x === y;
}
if (x.constructor !== y.constructor) {
return false;
}
if (x instanceof Function) {
return x === y;
}
if (x instanceof RegExp) {
return x === y;
}
if (x === y || x.valueOf() === y.valueOf()) {
return true;
}
if (Array.isArray(x) && x.length !== y.length) {
return false;
}
if (x instanceof Date) {
return false;
}
if (!(x instanceof Object)) {
return false;
}
if (!(y instanceof Object)) {
return false;
}
var p = Object.keys(x);
return Object.keys(y).every(function(i) {
return p.indexOf(i) !== -1;
}) && p.every(function(i) {
return deepEqual(x[i], y[i]);
});
};
var _checkCriteria = (item, criteria) => {
if (criteria.method !== void 0 && criteria.method.toLowerCase() !== item.method.toLowerCase()) {
return false;
}
if (criteria.url !== void 0 && criteria.url !== item.url) {
return false;
}
if (criteria.params !== void 0) {
if (item.config === void 0 || !item.config.params || typeof item.config.params !== "object") {
return false;
}
const paramsMatching = Object.entries(criteria.params).every(([key, value]) => deepEqual(item.config.params[key], value));
if (!paramsMatching) {
return false;
}
}
return true;
};
MockAxios.getReqMatching = (criteria) => {
return _findReqByPredicate((x) => _checkCriteria(x, criteria));
};
MockAxios.getReqByUrl = (url) => {
return MockAxios.getReqMatching({ url });
};
MockAxios.getReqByMatchUrl = (url) => {
return _findReqByPredicate((x) => url.test(x.url));
};
MockAxios.getReqByRegex = (opts) => {
return _findReqByPredicate((x) => Object.entries(opts).every(([key, value]) => value.test(JSON.stringify(x[key]))));
};
MockAxios.queue = () => {
return _pending_requests;
};
MockAxios.reset = () => {
_pending_requests.splice(0, _pending_requests.length);
MockAxios.get.mockClear();
MockAxios.post.mockClear();
MockAxios.put.mockClear();
MockAxios.patch.mockClear();
MockAxios.delete.mockClear();
MockAxios.head.mockClear();
MockAxios.options.mockClear();
MockAxios.request.mockClear();
MockAxios.all.mockClear();
MockAxios.interceptors.request.clear();
MockAxios.interceptors.response.clear();
};
MockAxios.useRequestHandler = (handler) => {
_requestHandler = handler;
};
MockAxios.Cancel = Cancel_default;
MockAxios.CancelToken = CancelToken;
MockAxios.isCancel = (u) => {
return !!(u && u.__CANCEL__);
};
var mock_axios_default = MockAxios;
// lib/index.ts
var lib_default = mock_axios_default;
export {
lib_default as default
};
/**
* TypeScript version of Axios mock for unit testing with [Jest](https://facebook.github.io/jest/).
* This file is based on https://gist.github.com/tux4/36006a1859323f779ab0
*
* @author knee-cola <nikola.derezic@gmail.com>
* @license @license MIT License, http://www.opensource.org/licenses/MIT
*/