How to Test an eCommerce Cart React Component
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo 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.
Get unlimited access to Fullstack React with TypeScript Masterclass with a single-time purchase.

[00:00 - 01:33] The card component. Open SRC, Card, Card TSX, and look at the card component. Here we use the use card context to receive the card data, the products and the methods to remove from card and get that total price. And also the card component has a condition in the layout code. It checks if there are products in the card, and if they are not, then it renders an empty card message, your card is empty, and also a link to the main page. When there are products in the card, it renders the list of products, renders the total price, renders the go to checkout button, and when you click on it, it should redirect you to the checkout page. Let's test all that. Create a new file, Card, spec, TSX, and there, let's plan the tests first. Describe card. There will be two main branches with the products and without the products, because they define two different behaviors that our card can perform. First, let's test the without product state. Describe without products . Here we, first of all, want to test that it will render an empty card message. Eat, to do, renders, empty card message. Then we want to test that if the user clicks on it, then they will be redirected to the main page, to the root. So we add another describe, describe on back to main page, click, eat, to do, and here we expect that it redirects to root.
[01:34 - 02:28] Alright, another big describe block is going to be with products. Describe with products . Here we want to test that the card will render the products list and the total price . Eat, to do, renders, card, products, list with total price. Here we also can click a link that says go to checkout, and then it will redirect you to the checkout page. Desc ribe on go to checkout, click, eat, to do redirects to checkout. Alright, let's start with the easiest test. Let's verify that it will show an empty card message when there are no products . Impert, card, from card, and import the use card context from the card context module.
[02:29 - 04:07] We're importing the use card context so that we'll be able to mock it. Just mock card context. Every time you need some external data, some values from the server, it's better to mock it if you want to write an isolated test. Pass in the mocking function. Here we want to return an object. This is why I'm wrapping the curly braces into round brackets. And I 'm mocking use card context. I say that it's going to be just a fan so that later we can mock the return value. We also need to tinker with the types a little bit and define use card context mock that will have the proper type. const use card context mock equals use card context. First we cast it to unknown as unknown. And then we cast it to just mock where we pass partial of the return type of the type of use card context. So we did a bunch of things here. First we defined the use card context as unknown. That's the fix the difference between the card context and the just mock types. Then we typed it as just mock from partial type of the return type of the use card context hook. This way we'll be able to avoid passing all the properties that use card context usually returns. So it will be easier to mock the values of the use card context. And then we assigned it to use card context mock. Now in our test, we can say that use card context mock mock return value.
[04:08 - 04:49] And we say that it will have products empty array. Actually, as we have two cases without the products, we can even define a before each block where we mock the use card context with an empty products list. Let's move it here. And now inside of the renders empty cart message, we can render the component const container equals render with router. And here we pass a cart. After we've rendered it, we can expect that container inner HTML contains a message, your cart is empty. Everything is good and the test is passing.
[04:50 - 05:58] Let's write the next test. Here we'll want to test what happens when we click on the back to the main page button or blink, render the cart will need get by text and the history to verify that we're at the right route, render with router. Here we render the cart. Then we fire event, click, we want to pass an element that we can get by text, where the text says back to main page. Next, we want to expect that history location path name equals the root route. It is important to write the strings exactly. So here I missed a dot. And this is why the test was failing. All right, now it's passing. And we can continue. And we can proceed with the width products describe block. Here we also can define a before each, before each. And here we mock the products as an array with two elements. First one has name product, full price, 100 image image, full source PNG. The second one is quite similar.
[05:59 - 07:16] The name should say product bar, price is 100. And the image is bar source, mock the return value of the use card context mock use card context mock mock return value passing an object with products. And the total price, we can make it a function that always returns 55. We don't care about the real value of this mock, because we don't really care to really calculate the price, because we're not testing the use card context hook here, we're testing only the cart component. So we can safely mock the total price. Now let's test that it will render the product list with a total price, remove the to do at the callback. And here we'll need some way to tell that we've rendered the elements . Right now the cart component renders card items. And it's going to be easier if we will mock this component. So import cart item props from cart item, and then mock using just mock the cart item module pass the mocking function. Here we want to mock the cart item expert, it's going to be a function that will receive a product, we define it as cart item props.
[07:17 - 08:51] And then we'll return a div that will contain the name price and image of the product. Let's get them name price image equals product. Now inside of this div render name space price space image. Now we can scroll down to the test, render the cart will get the container equals render with router, we render the cart. Now we expect that container inner HTML matches product, full, that's the name of the product, 100, that's the price, and image , full source, PNG, that's the image. We also expect to see another element as well. It should also match product bar 100 bar source PNG. The test is passing, then we know that we've rendered the cart items. Now we want to check if the total price is rendered correctly, expect container inner HTML to match total 55 zorkmets. Finally, let's test the go to check out click, remove the to do add a callback, render the cart, we will need get by text and history , render with router, here we render the cart, call fire event, click get by text, go to checkout. Now we can expect that history location path name equals checkout.
[08:52 - 08:55] Congratulations, you've just tested the cart component.