Check out a free preview of the full Intermediate React, v5 course:
The "Testing Mocks" Lesson is part of the full, Intermediate React, v5 course featured in this preview video. Here's what you'd learn in this lesson:

Brian uses the mockReponseOnce() method to test an API request. A mocked breedlist is passed to the request. When the result is received, the test validates the request was successful and checks the breeds returned are equal to the mocked data.

Get Unlimited Access Now

Transcript from the "Testing Mocks" Lesson

[00:00:00]
>> So, so far all we're testing in this useBreedList test is an empty array. Which here carousel, no carousel, not useBreedList. That's part of the story, but we want to test like that it calls the right API that we get back the right information and that it presents the user back with the correct information, if that's the case.

[00:00:25] The problem here is that under the hood, this useBreedList is using fetchBreedList, and fetchBreedList is using what? Fetch. I don't actually really want to hit my API, right. You can imagine a case where like, everyone's running all their tests and you're just hammering your production API. Not a good idea.

[00:00:46] It'd be great if we could mock it. So in general, I don't suggest mocking too many things. The one place where I'm like, okay, you can mock that API request. I'm okay with you fetch or mocking fetch, basically. There's a ton of ways to do this. I'm just gonna show you the easy way to mock request.

[00:01:06] Just to npm install -D vitest-fetch-mock. This is very similar to just fetch mock, 0.2.1. There's other ways to do this, you can actually just go write a mock for yourself they're very very simple pieces of software. But yolo, I don't like doing it, so I'm not gonna do it.

[00:01:31] And I'm not gonna make you do it. Okay, inside of test, inside of your vite.config, Just put setup files. And we're just gonna make a setup file really quick. It's gonna be called ./setupVitest.js. Okay. Make a file inside of source called, as you might have guessed, setupVitest.js. This is just a file that would get run before all of your tests get run.

[00:02:08] So if you had other environmental variables to set, this is where you would do it. In our particular case, we're just going to import creatFetchMock from vitest-fetch-mock. We're going to import vi from vitest. There is a const fetchMock = createFetchMock(vi), fetchMock.enableMocks. This is going to now universally enable mocks on fetch throughout your entire application.

[00:02:58] Your entire test suite is probably more accurately stated. I forgot what vi precisely is, it's the vitest utilities, okay. So it has things that createFetchMock goes and sets all the correct things up for you. I've never used it directly but that's exactly what it's doing. Okay, now we have all that enabled, we can go back to our tests here in useBreedList, okay.

[00:03:28] Up here next to renderHook, we're going to grab a function called waitFor, and then we're going to down here at the bottom right our test. So we're gonna write a test, gives back breeds when given animal. Okay, and then we're gonna give a dog which is going to give us back our function.

[00:03:55] This needs to be an async function, okay. And then just give it a bunch of breeds. Rather than type all them I'm just gonna copy and paste all these breeds that I have here. But feel free to write your own. I just grabbed some of them that I made in the API here so having to use Bichon Frise and so on and so forth.

[00:04:20] And then with here we're gonna say fetch.MockResponseOnce, okay. Here we're just saying next time fetches called respond with blah. You can be more specific of like they must call this particular URL. We're not gonna be so clever, right. We're just gonna to say mockResponse, the next one just blindly spit this back at them.

[00:04:49] Animal, dog and breeds right so respond with this. Okay, now we can come up here and copy and paste this business. Cuz I don't wanna write all of this again. And the only difference here is const result renderHook instead of giving it an empty string here, we're gonna give it dog.

[00:05:13] Okay, this will give us back our result. Now we can't just go test this right away because it's gonna go do fetch, right. Fetch is not synchronous. So it's asynchronous. So we have to wait for it. Hence waitFor is what we're gonna use. We're gonna say await waitFor, then you're gonna give it a function of what it's waiting on.

[00:05:34] So in this case we're gonna give it a test of expect(result.current[1]). And if you remember this is a hook, if we look at let's look at, let's look at our tests really quick here, breedList. The first one is the breed list the second one is the status. So we're gonna wait until the status is success, right.

[00:06:02] So let's do that waitFor result(current [1]) to be success. So this is gonna wait until this ends up happening or until time's out, one of the two things. And then after that we can say const breedList = result.current. And then here I can say expect(breedList) toEqual(breeds). Okay, so it's gonna be equal to this, whatever we got back from the API.

[00:06:51] We're gonna expect that to come backfFrom our useBreedList. So let's save that let's look at our tests. And we got an error, okay, well that's different. Well, that is yet a different thing let's check out what's going on here. So we have gives back breeds when given an animal is async function.

[00:07:26] Breeds, Fetch mockResponseOnce JSON, yes that's what it is. JSON.stringify. Right this needs to be, It doesn't give you back an object it gives you back a string which then fetch then decodes for you. There we go. And now there you go. That's a passing test. Okay, so that is how you can test asynchronous function.

[00:08:04] I showed you with regards to hooks and custom hooks and that kind of stuff. But that works with components, that works with anything that you have to mock fetch with vitest or jest. We used the vitest mock fetch. There's also a jest mock fetch that works precisely the same way.