axios-mock-adapter vs fetch-mock vs msw vs nock
HTTP Request Mocking Libraries
axios-mock-adapterfetch-mockmswnockSimilar Packages:

HTTP Request Mocking Libraries

HTTP request mocking libraries are essential tools in web development that allow developers to simulate API responses for testing purposes. They enable developers to create controlled environments where they can test their applications without relying on actual backend services. This is particularly useful for unit testing, integration testing, and end-to-end testing, as it helps in isolating the frontend from backend dependencies and ensures that tests can be run consistently and reliably. Each library offers unique features and methodologies for mocking HTTP requests, catering to different testing needs and preferences.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
axios-mock-adapter03,55167.9 kB96a year agoMIT
fetch-mock01,309157 kB95 months agoMIT
msw017,7634.92 MB425 days agoMIT
nock013,090185 kB88a month agoMIT

Feature Comparison: axios-mock-adapter vs fetch-mock vs msw vs nock

Integration

  • axios-mock-adapter:

    Axios-mock-adapter is designed to work specifically with Axios, making it easy to mock requests made through Axios instances. This tight integration allows you to set up mocks directly on your Axios instance, providing a straightforward approach for testing components that depend on Axios for data fetching.

  • fetch-mock:

    Fetch-mock is built to work with the Fetch API, allowing you to mock fetch requests easily. It provides a flexible API for defining responses and can be used in various testing frameworks, making it versatile for different testing setups.

  • msw:

    MSW operates at the network level, intercepting requests made by the Fetch API or XMLHttpRequest. This allows for a more realistic simulation of API interactions, making it suitable for both unit and integration tests. It can also be integrated with popular testing libraries like Jest and Testing Library.

  • nock:

    Nock is specifically designed for Node.js applications and provides a powerful way to mock HTTP requests. It allows you to define expected requests and their responses, making it ideal for testing server-side code and APIs without making actual network calls.

Flexibility

  • axios-mock-adapter:

    Axios-mock-adapter offers a flexible way to define request matching and response behaviors. You can easily configure it to return different responses based on request parameters, headers, and more, allowing for comprehensive testing scenarios.

  • fetch-mock:

    Fetch-mock provides a highly flexible API for mocking responses. You can define responses based on URL patterns, request methods, and even request bodies, giving you fine-grained control over how your mocks behave during tests.

  • msw:

    MSW's flexibility lies in its ability to mock any type of network request, including REST and GraphQL. You can define handlers for various endpoints and response scenarios, making it easy to simulate complex API interactions and error handling.

  • nock:

    Nock allows for extensive customization of request matching and response behavior. You can match requests based on URL, HTTP method, headers, and even request body, providing a high level of control over your mocked interactions.

Testing Environment

  • axios-mock-adapter:

    Axios-mock-adapter is primarily used in unit tests where you want to isolate components that rely on Axios for data fetching. It allows you to simulate various API responses without making actual network calls, ensuring your tests run quickly and reliably.

  • fetch-mock:

    Fetch-mock is suitable for both unit and integration tests. It allows you to mock fetch requests in a controlled manner, making it easy to simulate different scenarios and test how your application handles various API responses.

  • msw:

    MSW is ideal for integration testing as it intercepts actual network requests, providing a realistic testing environment. It allows you to test how your application interacts with APIs in a way that closely resembles production behavior, making it great for end-to-end testing.

  • nock:

    Nock is best suited for testing server-side applications in Node.js. It allows you to simulate HTTP requests and responses, making it easy to test how your server handles various API interactions without relying on external services.

Ease of Use

  • axios-mock-adapter:

    Axios-mock-adapter is straightforward to set up and use, especially for developers already familiar with Axios. Its API is intuitive, allowing for quick configuration of mocks and easy integration into existing test suites.

  • fetch-mock:

    Fetch-mock is user-friendly and provides a simple API for defining mocks. Its flexibility and ease of use make it a popular choice for developers looking to mock fetch requests without much overhead.

  • msw:

    MSW has a slightly steeper learning curve due to its network-level interception capabilities, but it offers comprehensive documentation and examples, making it easier to adopt for those familiar with modern testing practices.

  • nock:

    Nock is easy to use for Node.js developers, with a clear API for defining request expectations and responses. However, it may require more setup compared to client-side libraries, as it is focused on server-side testing.

Community and Support

  • axios-mock-adapter:

    Axios-mock-adapter has a solid community and is widely used among developers who utilize Axios. It benefits from the popularity of Axios, ensuring good support and regular updates.

  • fetch-mock:

    Fetch-mock has a growing community and is actively maintained. Its popularity among developers using the Fetch API ensures that you can find resources and support easily.

  • msw:

    MSW has gained significant traction in the developer community due to its innovative approach to mocking. It is well-documented and has a supportive community, making it a great choice for modern applications.

  • nock:

    Nock has a strong presence in the Node.js community and is widely used for testing HTTP requests. It has good documentation and community support, making it a reliable choice for server-side testing.

How to Choose: axios-mock-adapter vs fetch-mock vs msw vs nock

  • axios-mock-adapter:

    Choose axios-mock-adapter if you are already using Axios for making HTTP requests in your application. It seamlessly integrates with Axios and allows for easy mocking of requests and responses, making it ideal for unit testing components that rely on Axios.

  • fetch-mock:

    Select fetch-mock if your application uses the Fetch API for making HTTP requests. It provides a simple and flexible API for mocking fetch calls, allowing you to simulate various response scenarios and control the behavior of your fetch requests during testing.

  • msw:

    Opt for MSW (Mock Service Worker) if you want to mock both REST and GraphQL APIs at the network level. MSW intercepts actual network requests in the browser or Node.js, providing a more realistic testing environment. It is particularly useful for integration tests and can be used in both frontend and backend applications.

  • nock:

    Choose nock if you are working in a Node.js environment and need to mock HTTP requests for testing server-side code. Nock allows you to intercept and modify HTTP requests, making it ideal for testing APIs and services without making actual network calls.

README for axios-mock-adapter

axios-mock-adapter

Axios adapter that allows to easily mock requests

Installation

Using npm:

$ npm install axios-mock-adapter --save-dev

It's also available as a UMD build:

axios-mock-adapter works on Node as well as in a browser, it works with axios v0.17.0 and above.

Example

Mocking a GET request

const axios = require("axios");
const AxiosMockAdapter = require("axios-mock-adapter");

// This sets the mock adapter on the default instance
const mock = new AxiosMockAdapter(axios);

// Mock any GET request to /users
// arguments for reply are (status, data, headers)
mock.onGet("/users").reply(200, {
  users: [{ id: 1, name: "John Smith" }],
});

axios.get("/users").then(function (response) {
  console.log(response.data);
});

Mocking a GET request with specific parameters

const axios = require("axios");
const AxiosMockAdapter = require("axios-mock-adapter");

// This sets the mock adapter on the default instance
const mock = new AxiosMockAdapter(axios);

// Mock GET request to /users when param `searchText` is 'John'
// arguments for reply are (status, data, headers)
mock.onGet("/users", { params: { searchText: "John" } }).reply(200, {
  users: [{ id: 1, name: "John Smith" }],
});

axios
  .get("/users", { params: { searchText: "John" } })
  .then(function (response) {
    console.log(response.data);
  });

When using params, you must match all key/value pairs passed to that option.

To add a delay to responses, specify a delay amount (in milliseconds) when instantiating the adapter

// All requests using this instance will have a 2 seconds delay:
const mock = new AxiosMockAdapter(axiosInstance, { delayResponse: 2000 });

You can restore the original adapter (which will remove the mocking behavior)

mock.restore();

You can also reset the registered mock handlers with resetHandlers

mock.resetHandlers();

You can reset both registered mock handlers and history items with reset

mock.reset();

reset is different from restore in that restore removes the mocking from the axios instance completely, whereas reset only removes all mock handlers that were added with onGet, onPost, etc. but leaves the mocking in place.

Mock a low level network error

// Returns a failed promise with Error('Network Error');
mock.onGet("/users").networkError();

// networkErrorOnce can be used to mock a network error only once
mock.onGet("/users").networkErrorOnce();

Mock a network timeout

// Returns a failed promise with Error with code set to 'ECONNABORTED'
mock.onGet("/users").timeout();

// timeoutOnce can be used to mock a timeout only once
mock.onGet("/users").timeoutOnce();

Passing a function to reply

mock.onGet("/users").reply(function (config) {
  // `config` is the axios config and contains things like the url

  // return an array in the form of [status, data, headers]
  return [
    200,
    {
      users: [{ id: 1, name: "John Smith" }],
    },
  ];
});

Passing a function to reply that returns an axios request, essentially mocking a redirect

mock.onPost("/foo").reply(function (config) {
  return axios.get("/bar");
});

Using a regex

mock.onGet(/\/users\/\d+/).reply(function (config) {
  // the actual id can be grabbed from config.url

  return [200, {}];
});

Using variables in regex

const usersUri = "/users";
const url = new RegExp(`${usersUri}/*`);

mock.onGet(url).reply(200, users);

Specify no path to match by verb alone

// Reject all POST requests with HTTP 500
mock.onPost().reply(500);

Chaining is also supported

mock.onGet("/users").reply(200, users).onGet("/posts").reply(200, posts);

.replyOnce() can be used to let the mock only reply once

mock
  .onGet("/users")
  .replyOnce(200, users) // After the first request to /users, this handler is removed
  .onGet("/users")
  .replyOnce(500); // The second request to /users will have status code 500
// Any following request would return a 404 since there are
// no matching handlers left

Mocking any request to a given url

// mocks GET, POST, ... requests to /foo
mock.onAny("/foo").reply(200);

.onAny can be useful when you want to test for a specific order of requests

// Expected order of requests:
const responses = [
  ["GET", "/foo", 200, { foo: "bar" }],
  ["POST", "/bar", 200],
  ["PUT", "/baz", 200],
];

// Match ALL requests
mock.onAny().reply((config) => {
  const [method, url, ...response] = responses.shift();
  if (config.url === url && config.method.toUpperCase() === method)
    return response;
  // Unexpected request, error out
  return [500, {}];
});

Requests that do not map to a mock handler are rejected with a HTTP 404 response. Since handlers are matched in order, a final onAny() can be used to change the default behaviour

// Mock GET requests to /foo, reject all others with HTTP 500
mock.onGet("/foo").reply(200).onAny().reply(500);

Mocking a request with a specific request body/data

mock.onPut("/product", { id: 4, name: "foo" }).reply(204);

Using an asymmetric matcher, for example Jest matchers

mock
  .onPost(
    "/product",
    { id: 1 },
    {
      headers: expect.objectContaining({
        Authorization: expect.stringMatching(/^Basic /),
      })
    }
  )
  .reply(204);

Using a custom asymmetric matcher (any object that has a asymmetricMatch property)

mock
  .onPost("/product", {
    asymmetricMatch: function (actual) {
      return ["computer", "phone"].includes(actual["type"]);
    },
  })
  .reply(204);

.passThrough() forwards the matched request over network

// Mock POST requests to /api with HTTP 201, but forward
// GET requests to server
mock
  .onPost(/^\/api/)
  .reply(201)
  .onGet(/^\/api/)
  .passThrough();

Recall that the order of handlers is significant

// Mock specific requests, but let unmatched ones through
mock
  .onGet("/foo")
  .reply(200)
  .onPut("/bar", { xyz: "abc" })
  .reply(204)
  .onAny()
  .passThrough();

Note that passThrough requests are not subject to delaying by delayResponse.

If you set onNoMatch option to passthrough all requests would be forwarded over network by default

// Mock all requests to /foo with HTTP 200, but forward
// any others requests to server
const mock = new AxiosMockAdapter(axiosInstance, { onNoMatch: "passthrough" });

mock.onAny("/foo").reply(200);

Using onNoMatch option with throwException to throw an exception when a request is made without match any handler. It's helpful to debug your test mocks.

const mock = new AxiosMockAdapter(axiosInstance, { onNoMatch: "throwException" });

mock.onAny("/foo").reply(200);

axios.get("/unexistent-path");

// Exception message on console:
//
// Could not find mock for: 
// {
//   "method": "get",
//   "url": "http://localhost/unexistent-path"
// }

As of 1.7.0, reply function may return a Promise:

mock.onGet("/product").reply(function (config) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      if (Math.random() > 0.1) {
        resolve([200, { id: 4, name: "foo" }]);
      } else {
        // reject() reason will be passed as-is.
        // Use HTTP error status code to simulate server failure.
        resolve([500, { success: false }]);
      }
    }, 1000);
  });
});

Composing from multiple sources with Promises:

const normalAxios = axios.create();
const mockAxios = axios.create();
const mock = new AxiosMockAdapter(mockAxios);

mock
  .onGet("/orders")
  .reply(() =>
    Promise.all([
      normalAxios.get("/api/v1/orders").then((resp) => resp.data),
      normalAxios.get("/api/v2/orders").then((resp) => resp.data),
      { id: "-1", content: "extra row 1" },
      { id: "-2", content: "extra row 2" },
    ]).then((sources) => [
      200,
      sources.reduce((agg, source) => agg.concat(source)),
    ])
  );

History

The history property allows you to enumerate existing axios request objects. The property is an object of verb keys referencing arrays of request objects.

This is useful for testing.

describe("Feature", () => {
  it("requests an endpoint", (done) => {
    const mock = new AxiosMockAdapter(axios);
    mock.onPost("/endpoint").replyOnce(200);

    feature
      .request()
      .then(() => {
        expect(mock.history.post.length).toBe(1);
        expect(mock.history.post[0].data).toBe(JSON.stringify({ foo: "bar" }));
      })
      .then(done)
      .catch(done.fail);
  });
});

You can clear the history with resetHistory

mock.resetHistory();