DEV Community

Cover image for The only 3 steps you need to mock an API call in Jest

The only 3 steps you need to mock an API call in Jest

Zak Laughton on February 02, 2020

I recently found myself working in a Javascript codebase where I needed to implement new Jest tests. I knew very little at the time about writing t...
Collapse
 
chiubaca profile image
Alex Chiu • Edited

Thanks for this, very useful. I'm having a bit of trouble with this though...
my mockResolvedResponse is being returned undefined and I have no idea why!

import axios from "axios";
import { Users } from "./api-call"

jest.mock('axios')

describe('axios tests with mocking', () => {
  test('should fetch posts', async () => {

    const fakeResp = [
      {
        "userId": 1,
        "id": 2,
        "title": "qui est esse",
        "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
      }]

    mockedAxios.get.mockRejectedValue('Network error: Something went wrong');
    mockedAxios.get.mockResolvedValue(fakeResp)

    const axiosSpy = spyOn(mockedAxios, 'get')

    const result = await Users.all()

    expect(result).toEqual(fakeResp)  //❌Fails....
    expect(axiosSpy).toHaveBeenCalledTimes(1)  //✔Passes!

  });

});
Enter fullscreen mode Exit fullscreen mode

any ideas if I'm doing something silly?

Collapse
 
zaklaughton profile image
Zak Laughton • Edited

Sure! I'm not sure exactly what the root cause is, but I've got some troubleshooting steps to start.

My observations

jest.mock() vs jest.spyOn()

Looks like here you are using jest.mock() and jest.spyOn() here on the same function. Usually, these are used interchangeably, but not together. Both functions let you inspect how the function was called. The difference between the 2 is that jest.mock() completely blows away the original function being mocked, while jest.spyOn() keeps the original implementation so the function runs as it is was written. In most cases, I find I only need jest.mock(). (This article seems to do a good job diving into the comparison a bit more Understanding Jest mocks)

Here, it looks like you're spying on your mock, which is redundant, and might have unpredictable results. I'm not sure if that's the issue here, but it's a layer of complexity I'd take out. You should be able to check on the number of calls without the spy (see my suggestion in "What I'd do" below).

Mocking resolved and rejected values

Here, you're using mockedRejectedValue() and mockResolvedValue() on the same function:

mockedAxios.get.mockRejectedValue('Network error: Something went wrong');
mockedAxios.get.mockResolvedValue(fakeResp)
Enter fullscreen mode Exit fullscreen mode

This is redundant because each one will completely overwrite the mocked implementation, so first you set it to reject (no matter what), then you set it to resolve no matter what. Since your expected output (mockResolvedValue(fakeResp)) comes second, the .mockRejectedValue('Network error: Something went wrong') has no impact here. It won't change the output, but I'd remove it just to reduce the complexity for troubleshooting.

mockRejectedValue() is typically only needed if you are explicitly testing an error state (See also: Jest docs for mockRejectedValue() and mockResolvedValue()).

What I'd do

With the notes above, I'd remove some of the redundant code, then if it's still not working, dig into how the mocked function is being called:

  1. Remove the spyOn()

    - const axiosSpy = spyOn(mockedAxios, 'get')
        [...]
    - expect(axiosSpy).toHaveBeenCalledTimes(1) 
    + expect(axios.get).toHaveBeenCalledTimes(1) 
    
  2. Remove the mockRejectedValue()

    - mockedAxios.get.mockRejectedValue('Network error: Something went wrong');
    
  3. If the issue still isn't resolved, you can dig into what axios.get is being called with and what it's returning:

    console.log("axios.get() called with>>>", axios.get.mock.calls[0]);
    console.log("axios.get() returns>>>", axios.get.mock.results[0]);
    

    This should show exactly how axios.get() is being called in Users.all() (see more details on this type of mock call inspection in the jest docs here: Mock Functions). You can also throw some console.logs in the actual Users.all() function, too, which will also output to the terminal during the test.

Here's an example of what that console.log output looks like when I add it to the sample code from this article:

code screenshot

I hope this helps!

Collapse
 
chiubaca profile image
Alex Chiu • Edited

Wooah thanks for such a detailed reply!

I forgot to mention one crucial piece of information. I'm trying to do this with TypeScript! ** plot-twist! **

This means I get errors when trying to use axios.get.mock. I think this why I started playing around with jest spies, as it a bit more of type friendly method of getting the assertion metadata out.

Thread Thread
 
zaklaughton profile image
Zak Laughton

Ah, got it! Yeah, how to type mock functions is not immediately clear. Try this:

(axios.get as jest.Mock).mockResolvedValue(fakeResp)
Enter fullscreen mode Exit fullscreen mode

That should at least pass type checking and give you the auto-complete in your editor for mock functions. This should be good enough to at least get it working. If I remember correctly though, it won't actually check the types on the resolved value, so fakeResp could be any type, even if it doesn't match the return type of Users.all(). You'll also have to add as jest.Mock everywhere you call axios.get

If you want stricter typing for this without needing to cast as jest.Mock each time, I've had a great experience with ts-jest. Looks like they've updated a lot since I used it last, so I can't give a syntax example, but you can check out their docs.

tl;dr: use (axios.get as jest.Mock) for generic mock function types, or use a tool like ts-jest for stricter types of that specific mock function.

Thread Thread
 
chiubaca profile image
Alex Chiu

Thank you so much! Was finally able to get the test passing! The trick of using (axios.get as jest.Mock) was the key to letting me debug this thoroughly.

Collapse
 
ramyac032001 profile image
c Ramya

can i except the data in the screen to bind in the front end like
expect(screen.getByText(''my first album')).toBeInTheDocument();
but i try this above line ,it should not work .give any soltuion for that?

Collapse
 
viktorhsn profile image
Victor H Nascimento • Edited

Hi Zak,

Thank you very much for your article, it helped me a lot.
I am having trouble replicating this with typescript, it complains when I try to set the mockResolvedValue into axios get.

test("it should return permission true", async() => {
axios.get.mockResolvedValue({ //type error here.
true
});

expect(await wrapper.obterPermissaoUsuario("token","COD_APLIC","LIMIT")).toBe(true);
Enter fullscreen mode Exit fullscreen mode

});

Collapse
 
zaklaughton profile image
Zak Laughton

Hi Victor! Glad the article helped!

Typescript isn't great at determining the types of mocked values, but there are some great libraries to help. Personally, I've had great success using the mocked method from ts-jest. See details and usage examples here: ts-jest/test-helpers

Collapse
 
antoyne7 profile image
Antoine Braillard

try (axios.get as jest.Mock).mockReturnValue({})

Collapse
 
jikuja profile image
Janne Kujanpää

Is it possible to make jest.mock(<module>) call to create function calls which emits fail instead of returning null?

If you use such a scheme you know that all the function calls into mocked module are covered by user defined mocks. Would it make any sense?

Collapse
 
zaklaughton profile image
Zak Laughton • Edited

I think I see what you're saying: Returning undefined in a mocked endpoint is ambiguous, and it would be nice to instead return an error that clearly says "This endpoint/mock is not defined". I hadn't thought about before. Great idea!

Doing some research, I can't find a built-in Jest method to automatically make all function calls in a module fail, but you can create a manual mock file that will return an error for all functions using .mockImplementation():

// __mocks__/axios.js
const axios = jest.genMockFromModule('axios');

const throwUnmockedError = () => {
  throw new Error(`This endpoint has been mocked, but hasn't been given a manual response`);
};

// Make all axios methods return the unmocked error
// List of axios methods taken from README at https://github.com/axios/axios
axios.post.mockImplementation(throwUnmockedError);
axios.request.mockImplementation(throwUnmockedError);
axios.get.mockImplementation(throwUnmockedError);
axios.delete.mockImplementation(throwUnmockedError);
axios.head.mockImplementation(throwUnmockedError);
axios.options.mockImplementation(throwUnmockedError);
axios.post.mockImplementation(throwUnmockedError);
axios.put.mockImplementation(throwUnmockedError);
axios.patch.mockImplementation(throwUnmockedError);

module.exports = axios;
Enter fullscreen mode Exit fullscreen mode

Then, when you try to call a mocked function without a user-defined mock, the error will look something like this:

Jest unmocked output error screenshot

I created a branch on the demo repository that uses this strategy: mock-with-failed-requests. If you clone the repo, switch to that branch, and run npm run test:mocked, you'll get the error in the screenshot above.

If you play around with it a bit, there might also be a way to more clearly show exactly which mocked function triggered the error. You could also create a function to map through all the methods, which would clean up the manual mock and automatically include any additional methods added in the future.

I hope this helps!

Collapse
 
jikuja profile image
Janne Kujanpää

Throwing an exception is one solution butcode under test might catch exceptions but I have not found any nice way to do something simple like fail().

Looks like there has been plans for fail(<message>) in jest-extended(1) but is it still unimplemented.

(1) npmjs.com/package/jest-extended#fa...

Looks like:

const throwUnmockedError = () => {
  expect(0).toEqual(1)
};

does the trick but is not really pretty and I'm sure that there are use cases when that approach just will not work.

Thread Thread
 
zaklaughton profile image
Zak Laughton

Oh you're right! There's not a great way to fail a test from an imported module when the tested code is in a try/catch. I found some suggestions in this Github issue thread about using fail() or done.fail(), but I was unable to get this to fail the test from the imported module.

Best alternative I could think of would be to throw a console.warn() message so at least there's an obvious indication in the terminal of the missing mock. Otherwise, I'd imagine you'd have to build some sort of custom global Jest rule that fails when it hits an unmocked end point. This blog also looked like it might have some solutions, but I didn't have time to test them: Jest explicitly or arbitrarily force fail() a test.

I'm very curious about this. Let me know if you find any better solutions!

Collapse
 
mjeffe profile image
Matt Jeffery • Edited

Zak,

Great article, but I think you're missing a critical 4th step - resetting the mocks.

I just came across your post. I sure wish I'd found it earlier. Even though I'm an experienced programmer, I went through the same confusing process you describe when learning how to test Javascript with Jest. However, I knew enough about testing to know I needed to reset mocks after each test. There are subtle differences between the various reset options, but I generally do something like jest.resetAllMocks(); in a beforeEach(). I think you should at least mention the need for resetting, else the second test you write may not behave as expected.

Collapse
 
zaklaughton profile image
Zak Laughton • Edited

Great call-out! This is actually a best practice I've been ignoring in some of my own tests ("SHAME!"). I'll make an addendum to this article soon to add this detail and credit you for it. Thanks!

EDIT: Added

Collapse
 
flrnd profile image
Florian Rand • Edited

Hey Zak, this is really great! I've been recently facing a similar problem, what would you think it's the best approach when the API also has some kind of auth system, like jwt for example? Right now, the API I'm talking about is tested with supertest and I'd like to switch to jest (with its mocks, because it's a pain sometimes run the tests), and this article is going to be super-helpfull! Thanks for writing and sharing this!

Collapse
 
zaklaughton profile image
Zak Laughton

Hi Florian!

For this, I'd recommend abstracting out the API call into a separate module. This gives you a single place to test the authentication, and leaves the rest of your tests cleaner and easier to maintain.

For the example in the article, this would mean having an apiProxy.js module that we send the request to instead of axios. The proxy module would handle fetching and authentication, and in the test, we'd be mocking apiProxy instead of axios.

If you want to test the authentication in apiProxy.js, this is probably one of the few instances where you would actually want to make a network call to ensure the authentication is happening as expected at the end point. This can get complex based on exactly how the authentication is taking place and how your application is structured. But essentially, you'll want to use network requests to mimic how an actual logon takes place. In the case of JWT, you can make a login network request, then save the token in a variable and send it in the header for the rest of your authentication tests.

Collapse
 
flrnd profile image
Florian Rand

I think I get it! Thanks for the detailed explanation! I have a middleware that checks the tokens, so I think I'm closer to the solution than I thought I was. This saved me a lot of try/error! Cheers! And again, thanks!

Collapse
 
thodwris profile image
Theodoros Kokosioulis

Thanks for that! That's helpful. I've tried what you said but I'm having a hard time to integrate the ts-jest. Could you take a look at stackoverflow.com/questions/626040...

Collapse
 
zaklaughton profile image
Zak Laughton

Just posted an answer on that question. Hope it helps!

Collapse
 
diabl0269 profile image
Diabl0269

Hey Zak, I wanted to tell you that i open this account just to comment on your article.
I was trying to understand how to mock a function's return value and was looking for it for hours.
I must say that your explanation was short and sweet.
Thank you.

Collapse
 
zaklaughton profile image
Zak Laughton

Good to hear I'm not the only one who found this so difficult to figure out at first! 😁 Glad I could save you some time in the end!

Collapse
 
markskinsley profile image
Mark Skinsley

Hi Zak, this is a great article; thank you for breaking this down and explaining how testing works with API calls. Creating the mock is quite an unusual thing to get my head round!

I have a React site that does almost all its rendering based on the result of API calls. Normally I make an API call inside useEffect and render JSX based on whether data is returned. From my limited TDD knowledge... it seems test tests run on initial render, so I always receive the initial JSX, i.e. no results. Is there a way to simulate the API call and run tests on the JSX after a positive response from the API?

Collapse
 
zaklaughton profile image
Zak Laughton • Edited

Definitely! My first recommendation is to use React Testing Library on top of Jest. React Testing Library is quickly becoming the React testing standard due to its ease of use and opinionated approach.

If you're using React Testing Library, you can use a findBy query (docs), which waits up to 1000ms for an item to appear on the page.

It would look something like this:

import * from '@testing-library/react';

it('renders the fetched data', async () => {
    // Render the component with react testing library and
    // get the findByText() function to search the render
    const { findByText } = render(<MyComponent />);

    // Use the findBy function to wait up to 1000ms to find
    // the element that should appear after the fetch
    const elementImLookingFor = await findByText(/some text/)

    // Assert that it's in the rendered element
    expect(elementImLookingFor).toBeInTheDocument();
});

If you're not using React Testing Library, you can also manually use a 1000ms setTimeout() after rendering the element to wait a moment for it to finish fetching/loading before making your assertions.

I hope this helps!

Collapse
 
markskinsley profile image
Mark Skinsley

Hi Zak,

Thanks very much for the steer; React Testing Library seems to be the way to go for this sort of thing.

I think one issue I had was some of my packages were missing / out-of-date which was throwing some errors. In the end, after updating packages and importing @testing-library/jest-dom, I used this which seems to be working:

test('Data after re-render', async () => {
     render();
     expect(screen.queryByText(/test/)).toBeNull();
     expect(await screen.findByText(/test/)).toBeInTheDocument();
});

Thanks again,
Mark

Collapse
 
alanjereb profile image
Alan Jereb

To avoid mistakes and writing jest.resetAllMocks() after each test, you can use the following:

describe("My awesome test", () => {
    afterEach(() => {
       jest.resetAllMocks();
    });
    it("should do this and that", () => {
       ...
Enter fullscreen mode Exit fullscreen mode
Collapse
 
tapaibalazs profile image
Tápai Balázs

Nice one!

I am going to try this out tomorrow. :)

I just want to mention that a false-negative test is a test which is green but it should not be.
A false-positive test is red but it should not be.

The test case where you don't mock Axios is not a false-negative but a false-positive one. :)

Collapse
 
hareeshmhegde profile image
hareeshmhegde • Edited

i need to test response, Is mocking is requiered. Because I need to check actual response not mocked data. Please explain Iam a beginner it will be helpful.And iam not getting any jest resource reagarding api testing.It will be helpful.Thanks in advance

Collapse
 
zaklaughton profile image
Zak Laughton

Hi hareeshmhegde! Mocking is not required If you build the tests without mocks, the code will fetch data from the actual API endpoint just as it would when you are running the actual program.

These tests can be useful, but you want to keep them at a minimum to avoid slowing down your tests of making repeated calls and hammering the API. A common practice is to only hit the API in testing when running end-to-end tests ((such as with Cypress). These tests run slower, but are typically run less often than you'd run tests in Jest.

For example, you may run jest tests every time you save or commit with mocked APIs, then before you merge your branch into master, you can run the end-to-end tests to make sure everything works with the actual API.

Collapse
 
lucsan profile image
lucsan

Hi Zak, apologies for not having a problem for you, just wanted to say what an excellent piece, clear concise, well written, good examples.
If I might give a note, maybe a touch lighter on the journey, we all understand your pain.
Can I also add, I think you are giving top answers and help to those asking.

Collapse
 
nicolasnardi404 profile image
nicolasnardi404

wow thank you so much for this article. still super relevant in 2024 hehe
i am struggling a lot to understand mock and this article helped me a lot.
definitely will save me a lot of time. going crazy this days to try to figure out tests.
I started only a few months ago into coding and only now trying to get my head around tests - also a bit disappointed on why so many tutorials dont talk about testing your code from the beginning. omg its so important. thanks for make it simple and easy to understand.

Collapse
 
tylerjusfly profile image
Tyler

Hi, Zak. this still don't make sense to me. I understand you are mocking the axios right , and passing a value to it with the mockResolvedValue. but where i got confused is calling the getFirstAlbumTitle() but its not connected in any way to the value you are mocking and it seems like you are still calling the function normally as you did without the Jest.mock. How is it now getting value from the mock function.

Collapse
 
zaklaughton profile image
Zak Laughton

Thanks for the question! This confused me too, at first, and was a big driver for writing this article. This is the key part that explains it:

When you import a module into a test file, then call it in jest.mock(), you have complete control over all functions from that module, even if they're called inside another imported function.

axios is called in getFirstAlbumTitle(). Axios is not directly called in the test file, but the test file does call getFirstAlbumTitle(), which calls axios. Even though axios is called in a different file, it's still being mocked, because you set up the mock in the test file before calling the function that calls axios.

It might be clearer to see if we define the function in the test file:

// index.test.js
const axios = require('axios');

async function getFirstAlbumTitle() {
  const response = await axios.get('https://jsonplaceholder.typicode.com/albums');
  return response.data[0].title;
}

jest.mock('axios');

it('returns the title of the first album', async () => {
  axios.get.mockResolvedValue({
    data: [
      {
        userId: 1,
        id: 1,
        title: 'My First Album'
      },
      {
        userId: 1,
        id: 2,
        title: 'Album: The Sequel'
      }
    ]
  });

  const title = await getFirstAlbumTitle();
  expect(title).toEqual('My First Album');
});
Enter fullscreen mode Exit fullscreen mode

This makes the connection clearer for the purposes of demonstration, because we can see we are importing axios, including it in getFirstAlbumTitle() function definition, then mocking it. When you import the function instead...

const getFirstAlbumTitle = require('./index');
Enter fullscreen mode Exit fullscreen mode

...axios is still being mocked, even though it's not called directly in the test file.

Collapse
 
supriya_nakerikanti_5dc8a profile image
Supriya Nakerikanti

Hi Zak, This is very helpful. I am having a bit of trouble with this.

If a method is expecting the endpoint as one of its params, then how do i mock it and test the method?

test('test callAPI method', async () => {
jest.mock('axios');
axios.get.mockResolvedValue({
body: {
category: "2",
pinNo: "A-12-345-67",
pinValidity: "Valid",
planType: "Y",
relationShip: "D - Grandparent"
},
status: 200
});

const result = await callAPI();

const expected = {
    body: {
        category: "2",
        pinNo: "A-12-345-67",
        pinValidity: "Valid",
        planType: "Y",
        relationShip: "D - Grandparent"
    },
    status: 200
}

expect(result).toEqual(expected)
Enter fullscreen mode Exit fullscreen mode

});

I tried doing this and i am receiving the following error. I am trying to see if you could help me with this. Thanks in advance !

Error -

_axios.default.get.mockResolvedValue is not a function
TypeError: _axios.default.get.mockResolvedValue is not a function
at Object. (/Users/lnakerik/Desktop/eCommerce-showroom/showroom-web/ui.showroom/apps/na-showroom/src/utils/BudgetFilterPaymentOperations/BudgetFilterPaymentOperations.test.js:419:12)
at Promise.then.completed (/Users/lnakerik/Desktop/eCommerce-showroom/showroom-web/ui.showroom/node_modules/jest-circus/build/utils.js:276:28)
at new Promise ()
at callAsyncCircusFn (/Users/lnakerik/Desktop/eCommerce-showroom/showroom-web/ui.showroom/node_modules/jest-circus/build/utils.js:216:10)
at _callCircusTest (/Users/lnakerik/Desktop/eCommerce-showroom/showroom-web/ui.showroom/node_modules/jest-circus/build/run.js:212:40)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at _runTest (/Users/lnakerik/Desktop/eCommerce-showroom/showroom-web/ui.showroom/node_modules/jest-circus/build/run.js:149:3)
at _runTestsForDescribeBlock (/Users/lnakerik/Desktop/eCommerce-showroom/showroom-web/ui.showroom/node_modules/jest-circus/build/run.js:63:9)
at run (/Users/lnakerik/Desktop/eCommerce-showroom/showroom-web/ui.showroom/node_modules/jest-circus/build/run.js:25:3)
at runAndTransformResultsToJestFormat (/Users/lnakerik/Desktop/eCommerce-showroom/showroom-web/ui.showroom/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:176:21)
at jestAdapter (/Users/lnakerik/Desktop/eCommerce-showroom/showroom-web/ui.showroom/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:109:19)
at runTestInternal (/Users/lnakerik/Desktop/eCommerce-showroom/showroom-web/ui.showroom/node_modules/jest-runner/build/runTest.js:380:16)
at runTest (/Users/lnakerik/Desktop/eCommerce-showroom/showroom-web/ui.showroom/node_modules/jest-runner/build/runTest.js:472:34)

Collapse
 
sebastianvaliente profile image
Sebastian Valiente

Hey Zak,

Thanks for sharing this. I have a question - apologies if it was already asked.

I have a react-redux component that makes triggers multiple Axios calls (to a 3rd party API) both within the components method and via redux actions. Is there a way to use jest mock to specifically intercept each call and have different responses for each one?

I've been struggling with this and seeing how active you are in helping others and replying has given me hope! Thanks again.

Collapse
 
zaklaughton profile image
Zak Laughton

Hey Sebastian!

Unfortunately, I don't have too much experience with testing async redux functionality, and I think some of the solution would likely depend on exactly how your calls are implemented. You should be able to mock axios in the exact same way, but it may be a little trickier to predict exactly what is going to be called and in what order.

Unfortunately, I'm not the one who will have a helpful answer for you here, but I found a few resources that may help, in case you haven't seen them yet:

Sorry I don't have a better answer, but best of luck to you in finding a solution!

Collapse
 
ajshemi profile image
Akpojotor Shemi

enjoy this blog. could you share how you would do a mock post request. thanks.

Collapse
 
zaklaughton profile image
Zak Laughton

Sure! Mocking the post request is exactly the same as mocking the get request, except you'll want to mock the post method:

axios.post.mockResolvedValue({
    data: [
      {
        userId: 1,
        id: 1,
        title: 'My First Album'
      },
      {
        userId: 1,
        id: 2,
        title: 'Album: The Sequel'
      }
    ]
  });
Enter fullscreen mode Exit fullscreen mode

In this case, you'll want the mocked value to be whatever you get back from the real post response. I've found console.log()-ing the response to a real post request a good way to get a response to copy into the code.

If you want the mock to return a dynamic value based on the input, you could instead use axios.post.mockImplementation(...) This will allow you to create a custom function to build a response based on the input given to axios.post(). You can see the full documentation for mockImplementation() here.

I hope this helps!

Collapse
 
llermaly profile image
llermaly • Edited

I registered to say thanks. As you said is very hard to start from jest documentation.

Collapse
 
mirahekad profile image
MIRAH

Thank you for your post, it so help me to understand about testing API call

Collapse
 
bhatvikrant profile image
Vikrant Bhat

This was a great article! After a week of searching/sulking found exactly what I needed! Thanks @zaklaughton !

Collapse
 
zaklaughton profile image
Zak Laughton

Glad to hear it helped!

Collapse
 
sutar15sonali profile image
sutar15sonali

internal/modules/cjs/loader.js:955
throw err;
i am getting this error. Please help

Collapse
 
zaklaughton profile image
Zak Laughton

Hi Sutar. Not sure what the context is here. Is this related to the mocking in this article? What steps did you take that triggered the error?

Collapse
 
shimphillip profile image
Phillip Shim

Gotta do lunch and learn on this!

Collapse
 
kwamikudjie profile image
Kwami Kudjie

Thank you for the clean explanation

Collapse
 
adrienjoly profile image
Adrien Joly

Thanks for the very clear explanation, Zak!
I would like to mention two additional ways to mock:

  • mock the API responses at the HTTP level, to make the test agnostic to the library used to send those requests. E.g. « nock »
  • use dependency injection in your code, do you can inject a mock directly from your test, without having to rely on jest for this.
Collapse
 
nuculabs_dev profile image
Nucu Labs • Edited

Great article!

I like to wrap Axios functions under my own functions so I can mock them instead.

Collapse
 
zaklaughton profile image
Zak Laughton

Agreed! I usually like to abstract away axios functionality in custom functions. I mocked axios directly in this article though just for the purposes of keeping the mocking example simple.

Collapse
 
jb0925 profile image
Jesse Brink

I just wanted to say thank you for this! This really got me unblocked, so thank you for that.

Collapse
 
zaklaughton profile image
Zak Laughton

Awesome! Glad it helped!

Collapse
 
42b883 profile image
wriozumi

Thank you! This is the best article about Jest!

Collapse
 
zaklaughton profile image
Zak Laughton

Glad you found it helpful!

Collapse
 
adrberia profile image
Adrberia

Made this account just to say THANK YOU! I was up last night trying to test my fetch request using Thunks and this post was exactly what I needed and it works now!

Collapse
 
zaklaughton profile image
Zak Laughton

Awesome to hear! Glad I could help!

Collapse
 
piyushkadam5 profile image
Piyush Kadam • Edited

Awesome!, thanks for the article, I was stuck on the same problem..! not only it unblocked me but also it inspired me to go further into unit testing..a big thanks :)

Collapse
 
zaklaughton profile image
Zak Laughton

Sweeeeeet! Glad it helped!

Collapse
 
neutrinosunset profile image
Neutrino

That's great. But how do you mock an method of a class instead of a top level function that is exported directly?

Collapse
 
veromaia222 profile image
Veronica Maia

Have you tried supertest to make http requests?

Collapse
 
tammarut profile image
arima

OMG!
I have spent my 2 days to learn these!!
You save me a lot of times🎉

Thanks from Thailand 🇹🇭

Collapse
 
zaklaughton profile image
Zak Laughton

AWESOME!!!! Glad I could help! 🎉

Collapse
 
pthapa1 profile image
Pratik Thapa

Just wanted to say Thank You for this wonderful piece.

Collapse
 
espretto profile image
espretto

In order to mock API responses, use mswjs.io/