How to Test a React Home Page With Jest

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

This lesson preview is part of the Fullstack React with TypeScript Masterclass course and can be unlocked immediately with a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to Fullstack React with TypeScript Masterclass with a single-time purchase.

Thumbnail for the \newline course Fullstack React with TypeScript Masterclass
  • [00:00 - 00:09] Home page. Our home page renders a list of products that we get from our server . Open the SRC home folder and I'll walk you through the files here.

    [00:10 - 00:24] First of all, we have an index.ts file. It is used to control the visibility of the module contents. As you can see, we expert only the home component. The product component, or product card component, won't be visible outside this module.

    [00:25 - 00:58] The benefit of it is that the product card component won't be accidentally used on other pages. Sometimes you want this, but then it's better to put this kind of component into some kind of shared folder. Here I wanted to make clear that everything inside of the home folder belongs only to this particular page. Now let's define some tests. Create a new file, Home spec TSS and the home component gets the data from the use products hook and then does one of three things. While the products are still being loaded, it renders the loader.

    [00:59 - 01:22] If it gets an error during the loading process from the use products hook, it renders the error message that it got. When the products are loaded successfully, it renders the products list. Let's reflect it in our tests. I like to pre-plan my tests before I write them, so let's define a describe block for each of the cases that I've just listed. First, we define the describe for the whole home block.

    [01:23 - 02:25] Then we have three cases, describe while loading, describe with data and with error. Okay, we have three aspects where we want to write the test cases. For the with loading case, we will add a test, it to do, we can plan the tests using the to do keyword and we test that it renders the loader. For the with data case, we want to test that it renders categories with products and for the with error, we test it to do that it renders error message. Now as we get the data from the use products hook, we want to mock it because we want to test the home page in isolation. Just mock, we mock the whole use products module, we pass a function that will mock it and here we want to mock the use products with just a fan so that later we can mock the return value of it. If it would be JavaScript, then we could already start using this mock button.

    [02:26 - 03:35] TypeScript will need to adjust the type information. So we'll define another constant use products mock. It's going to be use products, but we will cast the type of it first to unknown so that we don't have any types compatibility issues because in TypeScript, if you try to cast types that are too different from each other, it might yell at you and say that you're trying to cast some incompatible types. So to avoid it, you first cast it to unknown and then you cast it to the desired type. In our case, we want to cast it to just mock type so that our use products mock has both the type, the properties of the use product hook and also the properties of the just mock because we will want to be able to, for example, mock the return value and the mock return value function only exists on the just mock and not the use products, but let's continue. So we mock it with the type partial of return type of type of use products. So what we did here is we used partial from the return type of the use product hook so that we don't have to mock all the values of its return type.

    [03:36 - 04:01] Partial modifies the return type for us making all the properties there optional. Okay, but we've defined our use products mock and we can continue. Let's define the with loading test. Here we want to test that we will render the loader, define the callback. Here we first mock the return value of the use products mock use products mock mock return value.

    [04:02 - 05:32] We wanted to have the loading state so categories is going to be an empty array is loading is going to be true and the error is going to be false. After we've mocked the return value and its loading state, we can render our home component const container equals render home. After we 've rendered it, we can verify expect that container inner HTML matches the text loading. We test that the loading text is there because this is how our loader component works. It just renders the text loading. Now let's test the with error state. Here we want to verify that our component will render an error message, define a callback. Here we can copy the mock definition. We will just have to adjust it a little bit pasted here is loading should be false error should be true and categories should be an empty array as well. We already rendered the home component. Now we expect container inner HTML to match error wait until the test passes. Everything is fine and we can define the with data test removed to do. And here our test is going to be a little bit more complex because our home components renders the product cards. If you open home TSX, you will see that when we have the data, we map through the category items. And for each item, we render a product card. If we want to test the home component in isolation, then we'll have to mock the product card as well.

    [05:33 - 06:13] Scroll up and mock the product card. First, let's import its types import product card props from product card. Then use just mock to mock the product card module, define the mocking function . It's going to return an object with field product card. That's our exported component. And we mock it as a functional component that receives data that it gets from the props, we imported product card props to be able to use them on this component as well. Now we get the name, price, and image from the datum.

    [06:14 - 06:51] And then we return div that renders name, price, and image. Let's fix the typo and save the file. Okay, scroll down to the test. Here we'll mock the category, const category, of type category, equals an object with fields name, category, full items. And the items is an array. For now, let's add only one object here, it will have name product, full price, 55, and image, test, JPEG. Now we can use this mocked category to mock the return value of the use products hook.

    [06:52 - 07:59] We say use products, mock mock return value, passing an object with categories. An array with this category is loading false error, false. Okay, now we render the home component, we get the container by calling render with the home. Finally, we can write the expectations, expect that container in our HTML matches the category title, because one of the things that our home component does, it renders the title for each of the categories you can see it in the layout, that in the map of the categories, it renders category name as the title, go back to the test. So we check that the container in our HTML will contain category, full. And then we also want to check that the product information was also in the layout. So we check that product, full 55 and test, JPEG is there with test for this string, because we've mocked our product card to just render div, that will render string containing name, price and image of each of the products. All right, and our test is passing now.