React Testing Tutorial (Jest + React Testing Library)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone today we're going to be writing tests for a react component using jest and the react testing library so to get started i'm going to use mpx to create my react app but you can create your react app however you want if you already have a react app that will also work now that that's finished we're going to move into that directory and we're going to open it in our code editor so i'm just going to open up the terminal here and i'm going to use npm start this is going to open our app in the browser and i'm just going to put this over to the right and i'm going to keep my code editor on the left so we can work on these at the same time this gives us the basic project of react app we can see it's running here so the first thing we're going to do is create our component we're going to put it inside a new directory called components and we're going to name this file to do.js as you can guess this component is going to render a to-do item for like a to-do list or something like that so the first thing we need to do is import react from react and then we're going to create our function and for now let's just return a div that says hello world like that and then we need to do export default to do so that's our basic component to begin with it's going to become more complex as we write some tests but for now let's go into app.js and let's use this component so we're going to remove everything inside the div and we're able to remove this line because we don't use logo anymore and then we're going to import to do from and it's inside the components directory to do and then we're able to use that component here like that so once we save it hot reloaded and we can see we have we're now rendering this component so now that we have this basic component we want to write a test for that so inside the components directory we're going to create a new folder and i just like to use this convention where um you create a directory with tests in this format and jest is going to be able to pick up that it's a test because if we create a new file we can call this to do dot test dot js unjest picks up files with this regex using dot test dot um so we're gonna be able to write our test in here just to show that this is actually running a test we can create a test here and if we do expect true dot to be true uh we'll be able to run our tests so we do get a simple test for free with react with create react app but we're actually going to delete this we're going to be doing something similar but we're going to be taking it to the next level and doing some more advanced things and we're going to be explaining how it all works so let's just delete this test for now cool so i'm going to stop my app and then i'm going to do mpm run test and the create react app sets all this up for us um we already have jest and this test script there so we can see we had one test and it passed and using this test script it actually watches for changes in our tests so if i for example change this to false the test is going to run again and it's going to see here that it failed obviously because it expected uh false and received true so let's change that back cool so as well as the packages that come by default with create react app we need to install two more things so the two things we need is this testing library react and i see we might actually already have it test library react but it's a dev dependency so let's just move it there and we also want this react test renderer that we're going to be using so let's just install them and save them cool and let's start the test script again and now let's create an actual test for our component so we need to import three things from the test and library react so let's import render screen and clean up and these are all coming from that testing library react so we can do that let's make this even smaller cool so we're importing these things from test and library react um and now our test is going to use those but our test needs to render the component that we just created so we also need to import that and because we're inside the test directory we need to go back one and then import to do so now we have everything we need to write our first test so let's just call this should render to do component and what we're going to do here is we're going to use the render function that we imported here and we're just going to pass in the component that we created so this to do component and this is actually going to render the component first and now we're able to retrieve it so we can say const to do element equals screen dot get by test id and this is something that we're going to change in our component actually so we can use screen and we can use that to retrieve a component from the tree using its test id and right now it doesn't have a test id but let's finish this um test out just so we can see it fails and then we can make a pass so let's give it a test id of to do one okay so now that we're doing this we want to now make some assertions on on this so we've acted we've set up we've acted and now we want to make some assertions on this so let's use expect and we can say to do element dot to be in the document and this is going to assert that it's in the document so this is actually going to fail now because as we know we don't have anything with this test id in the document so let's go back here and we're going to give this div a data test id of to do one so if i save that now it's still failing and that's because um we used the wrong method here so this should just be get by test id because we're assuming that there's only one there so now it's passing we can see it's retrieving this component and it's it's able to verify that it's there so we're able to do some more advanced things with this now so we can use expect to do element and we can use something like to have text content and we can verify that the test content we want is there so if we put hi and save we can see that this is actually going to fail because we actually have hello world so we can change that cool so this is a simple test testing a simple component but now we're going to make our component a little bit more advanced and we're going to give it some props so going back to the actual component what do we actually want this to do so we wanted to render a to-do item and we want the user to know whether the to-do item is completed or not so to do that first of all we need to pass something in as props and that's that to do and going back to app.js we're now going to define what our to do looks like so we're going to say const to do's we're going to create a list of them and each of them is going to have an id we give the first one an idf1 they're going to have a title we'll just say wash dishes and they're going to have a boolean whether it's completed or not and let's say that this one isn't complete let's create another one let's give it an id of two and this one is going to be completed and this is just going to be make dinner okay so now that we have some to do items we want to use those to do items uh as parameters for this to do component so we're going to open a block here and inside here we're going to map through our to-do's so as we're mapping through we want to return to do for each of those and it's going to take a parameter of an actual to-do which is the to-do that we're currently on so this is going to map through the whole array and for each one we're going to return a to do component so now we're able to remove this and save and we need to run our app again let's clean this up a little bit and now we can see because we have two to do items it's rendering hello world twice so that's that's what we want but now inside the actual component instead of rendering hello world we want to render the to-do item itself so let's grab the things that we need from the to-do so we know it has an id we know it has a title and it has a completed and these are coming from to do so first of all let's just use the title to see that it works so now instead of rendering hello world we can see it's rendering the title of each to do item this is a great start to begin with so the one thing we're not doing very well here um is showing whether the to-do is finished or not so let's do that first of all let's extract something here so we're going to say that first of all it's going to be inside a h1 tag and inside the h1 tag is going to be the title and now we want to check if it's completed so let's say const text equals we're going to use a ternary operator so if it's completed we want to use a strike tag um to basically strike out the to-do so inside here we're going to put the h1 strike and if it isn't completed um then we're just going to use the original hitch one without any strike around it so after that we want to return what we actually have found and that is the text so we're going to return the text so we can see now that looks nice um we also want this test id to use the test to use the id of the after to do item because these should be unique so let's put this inside here and let's just say it's to do and then we're going to pass in the id cool so this now functionally does exactly what we want to do but now we want to write some tests um to verify that it works as expected because then if we went and refactored this code we still want the test to pass we still want the behavior to be the same okay so let's stop our app and let's go back and run our test we only had one test before and it's probably actually going to fail now because it's no longer returning um a component that has text hello world so we can see we're we're getting some unexpected things here so um let's create our to-do item first of all so it's gonna have an id of one and let's we can actually just copy this from here let's use this okay and we can actually close our browser now because we know what it looks like we know it's it's not going to change we're just going to be writing tests now to verify that it's working as expected so closing that now we have a bit more room so now we have this to do item and as we did before we want to pass it in as a prop to our to do component so now let's see what part of this is failing because we should still be able to get this um to do because we still have the test id off to do dash on the id and so it should be in the document but what we're expecting to fail here is the text content which it is we can see um we're expecting the text uh to be hello world but it's actually washed issues which is actually what we want so let's change that and as you can see this to-do item isn't completed yet so let's uh rename this to should render non-completed to do and now things are getting a little bit easier because we can actually just copy this test and paste it and let's rename it should render completed to do and we want completed to be true now and let's just change this as well although it doesn't really need to be um changed we can say wash care so we still have an id of one um let's give it an id of two instead just to show it's still working um completed is true we're rendering that and we want to do two and if we save now uh this should still fail because we have this um this is incorrect this should be washcare cool so just to mention as well we're rendering all these items um what we should actually be doing is using this clean up method after each test to clean up everything to clean up the render so let's use after each so this is going to run after each test here so after each test we want to run cleanup and this is just going to make sure that everything is clean and every test is starting from the same starting point and there's nothing existing there already so our two tests are passing and that's great but we aren't yet testing whether the component is completed or not whether the to-do is completed or not so let's try to do that now how can we do that so we have this to do element and we're able to look at look at some things there so let's use expect to do element dot to it should be a html to contain html so we know that a completed to do uses this strike tag so we're actually able to use that and verify that it has this strike tag like that so the completed to do should have this strike tag if we copy this line and paste it up here we know that this to do shouldn't have this strike tag so this this test should actually fail now and we can fix this by inverting this by saying dot not so this is going to say this to do element should not have this html and now it's passing so that's great okay so this is some of the the basic things that we can do to basically check all of these different attributes and elements of the component but this is quite manual we have to verify all this but it's it's also a great test there's also another way that we can write these tests so we can use a snapshot um to verify that the component hasn't changed since the last time we ran the test so to do that we're going to import render from react test render this is the other library that we installed in the beginning so we can use this renderer now let's write another test and this is going to use snapshots so let's matches snapshot okay so again we're going to need to create our to do like this and now we're going to create a tree um of the component so we're going to render the component like this renderer.create it's going to be doing something similar here we're actually going to render this component and then from this tree we're able to convert to json so if we just for a second console.log what the tree looks like we should be able to take a look so we can see that this is actually actually the component tree so the the actual component itself is a div it has some props and it has some children so the children inside here is going to be like the child um elements here so it would be like strike and h1 so how can we use this snapshot so it's going to create that and then we're going to say expect tree dot 2 match snapshot and this is where the magic happens because if we take a look here in our components directory we have a test directory we have our test and we have a actual component once i save this it's going to run the test again and we're going to see something quite interesting happen so it's going to run our test we can see it created this new directory called snapshots and it actually contains our tree like that so going back here now into where the test ran we can see that something happened so it ran out three tests and we can see it also wrote a snapshot so it created a new snapshot from the test suite and now if i run this test again it's going to know that the snapshot already exists so it's not going to create another one and it's going to verify that this component still matches the snapshot which was created before so if i was to go back here and do something different here if i was to add to do dash to the h1 tag and save we can see that our test is actually going to fail now um so the first two tests still passed because our components still contain the text washed issues and washed care um but the last test about the snapshot failed and we can see here that it actually shows the diff of what what changed so given that um this we might have actually wanted this behavior we might have wanted um the to do to contain this extra text so if we actually wanted that we can update our snapshot so here we can see inspector code changes or press u to update them if we press u it's going to update the snapshot that was here and now the snapshot contains the new component tree and every time we run our test again it's going to test against the new snapshot and like that i can change it back and if i press u again we want to update the snapshot to what it was before now it's back to what it was so these these tests are quite finicky so if we change anything in our component the way it looks uh it's going to fail the test but it is good just to to verify what's actually being changed so i i do like snapshot testing but i also think that you need these other tests these other unit tests um to basically verify that some properties that are important to you are there um although these snapshot tests are more fragile i think they're also very valuable and you can use a mixture of both um probably works best so thanks for watching hope you enjoyed and i'll see you next time
Info
Channel: Kris Foster
Views: 29,319
Rating: 4.911252 out of 5
Keywords: testing react with jest, jest react tutorial, jest react testing library, jest react testing tutorial, react test renderer tutorial, react component testing, react component testing jest, how to test react components, jest react testing, jest testing react components, how to test react, react testing with jest, react testing 2021, react testing tutorial, how to test react app, how to test react components with jest
Id: ML5egqL3YFE
Channel Id: undefined
Length: 22min 16sec (1336 seconds)
Published: Sat Feb 27 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.