Unit Testing (Vitest) Tutorial #3 - Using Different Matchers
Skills:
Tool Use & Function Calling85%
Key Takeaways
This video tutorial series covers unit testing with Vitest, including setup and using different matchers to write effective unit tests for code. The tutorial demonstrates various matcher methods, such as is prime function testing and array content comparison, to assert expected behavior in tests.
Full Transcript
Okay then my friends. In the last lesson we made our first test suite and test cases to test the longest string function. And in those tests we used this single matcher method called to be which allowed us to assert that a certain value should be something or other. But there's a ton of different matches that we can use other than this to be one to assert different things. So in this lesson we're going to explore a few of those. And to do that, we'll be writing tests for a second function that I've created called is prime in this same examples.js file. Now, the function logic in itself is pretty simple. And to be honest, it's not really that important because like I said before, when we're writing tests for a function, we can kind of treat that function as a black box. Then if a test fails, we can open that black box and look inside. But essentially, it takes in a number as an argument. And then if the type of the argument is not a number, it throws an error. It also returns false if the number is less than one because zero and negative numbers cannot be primes. Then it looks at the number. It loops through other numbers then to determine if it is a prime or not by looking at its modulus or in other words the remainder. If it is a prime number, we return true. If it's not a prime number, we return false. Again, the function logic in itself is not really that important to us right now. We just want to test the expected behavior. So then let's head back to the test file where I've already prepped a brand new test suite for this new is prime function. And inside that test suite, I've also prepped a few test cases as well using the it function. We've seen how to do all of this before, which is why I've written it all out ahead of time. So we can just focus now on writing the test logic for each one of these cases. I've also imported the is prime function as well at the top of the file so that we can use it in all of those tests. Now before we start I want to mention one thing. The tests that we write in this lesson might not be the best way to test the function. And I'm only writing these tests to demonstrate the different matcher methods available to us and how we can use them. But then in the next lesson we'll delete all of these tests and we're going to write some better ones to test the function properly. All right then. So let's start with this first one. It returns true or truthy for small prime numbers. So we'll start by writing our first assertion which we can do by using the expect method. And then inside that we'll invoke the is prime function and pass in a number which we expect to be prime. So for example that could be two. Right? Now what do we expect then in this case? Well we would expect the result to be true. So we would use the same tob matcher and we would pass true as the value. Okay, so we've seen that before. Let's do another one now which is similar. So I'll copy this line of code onto the next line. And then I'm going to change the value to be another small number we would expect to be prime like three. And again we'd expect the return value of the function in this case to also be true. All right. So let's do one more by copying the line of code again down to the next line. And we're going to use another number that we would expect to be prime like five. And this time we're going to use a slightly different matcher called to be truthy and invoke it. And we don't need to pass an argument into this method because the method in itself declares what the value should be a truthy value. And that includes the boolean true. It would also include other truthy values as well like non-mpty strings or positive numbers or any kind of array or object. So it's much looser than checking for an exact boolean value of true, but sometimes it might be enough for you. All right. So now let's run these tests by coming to the terminal and we want to type npm run test and then we can hit enter and we should see that all of those three tests now pass. Awesome. Okay. So let's move on to the second test case. it returns false or falsy for non-p primes. Okay, so let's come in here and I'm going to say expect first of all and invoke that and then we'll invoke the is prime function within that. So we want to pass in here now something that is a non-prime. So for example one is not a prime and then we can say that is to be and we'll say false. Let's do another example. I'm going to say is prime and then pass in zero and then we'll say this is also false. So to be false again and we're going to use another match now which is the opposite of this one to be false. So let me duplicate this one more time and we'll give this a different number and that number is going to be four and we'd expect this to be false as well because it's not a prime number. It can be divided by two. So instead of saying to be false, we'll say to be falsy now. And then we don't need to pass in false. And again, this is much looser than checking for the boolean value of false because it can be any falsy value. And falsy values include things like null, undefined, empty strings, zero, negative numbers, etc. But anyway, let's save this file now and make sure everything still passes. I'm going to open the terminal, and we can see this one right here passes. Awesome. Okay, then. So the next one is this. It matches results in an array using two equal. And two equal is just the matcher we'll be using. And I'll explain what it does in a moment. But first of all, let's do a little bit of test setup. So what I want to do is use the is prime function on an array of numbers one after the other. And then I want to map the return values of those numbers true or false to a new array. Then we can assert that that array of values should be like true true false false or whatever it might be. So let me just paste in this simple snippet of code to set this up. And it looks something like this. We make an array called numbers which contains four numbers. Then we map that numbers array to a new array using the is prime function to return those new mapped values which are booleans. So this results array now should be an array of booleans true or false depending on whether those numbers were primes or not. And now we want to assert what this array should look like. So to do that, let's come down here and we're going to use the expect function again. And we're going to pass in the results array as the argument. Now you might be thinking, well, to test the array, we can just use the 2B matcher like this. And we can pass in the array as we expect it should be. In this case, that would be true for the first two positions because two and three are both prime numbers, right? And then for the third position, we'd expect false because four is not a prime number. Then true again for the last number, five, which is a prime. So you might think that this should work, but if we open the terminal now and check the test results, then you'll see it fails. And that's because the 2B matcher checks for strict equality, which means it compares where the two values are exactly the same thing in memory. So that works fine for numbers, strings, and booleans, simple values, but not for objects and arrays or any kind of reference type. Even if two arrays look identical, they're still different references in memory. So to be will always say they're not equal. So in those cases, we need to use a different matcher to check that the contents of the arrays or the objects are the same, not whether they're the same physical reference in memory. And one matcher we can use to do that is the is equal matcher. So if we change this to B matcher to be is equal and then save the file, we should see then that the test passes. All right. So let's move on to the next test case now, which is the one down here that says it detects primes in a filtered list. So again, I'm just going to paste in a little bit of setup code now, which looks like this. We've got an array of numbers again, this time 1 to 7 stored in this nums constant. Then we make a filtered list based on that initial one using the is prime function to filter out any numbers which are not primes. So this primes constant now should just be an array of only the prime numbers from that original array. Right? All right. So now we need to make an assertion for that by using the expect function again. And we're going to pass in the primes constants. Now this time I want to show you a matcher called to contain which we can use when we're checking something exists inside an array or inside a string. So this filtered array of primes should still contain seven, right? Because seven is a prime number and it shouldn't have been filtered from the list. So let's use the to contain matcher and we're going to pass seven in as the argument. Once we've done that, we can save the file and we're going to take a look at the test results in the terminal and we should see that everything still passes. All right, so let me just quickly do another example now, but this time we're going to check for a numbers lack of presence in the primes array. So we'll say expect again and pass in the primes array again, but this time I want to tack on a modifier called not. And then we'll add on the two contain matcher. And this modifier now changes how the matcher works because now we're saying we expect this primes array not to contain a certain value. For example, we'd expect it not to contain the number four because four is not a prime number. So we'll pass that in. And this not modifier is something we can add before pretty much any other matcher in vest as well like to be or to equal. Anyway, let's save this now. And then we can check in the terminal that all the tests still pass, which they should do. All right, so let's move on now to the next test case down here, which says it throws an error when passed a non-number. So if we go back to the function itself, you're going to see that the first thing we do inside that function is check if the argument passed in was actually a number. And if it's not a number, we throw this error with an error message that says input must be a number. So in the test now, we want to check that that works by passing something like a string as the argument to the function. And we can do that. We can assert that errors get thrown under certain conditions. So first of all we need to invoke the function somehow with an invalid input so that v test can check for the error. But if I just invoke the function directly here like this by calling is prime and then passing in a string like Pikachu then this function will get executed and throw the error before we even make an assertion and vest won't get the chance to test it because our code's already thrown that error. So instead we need to wrap this function call within another function which doesn't yet get executed. For example, I could make a constant called bad call, right? And I could set that equal to a function which then wraps the is prime function call. And now when this line of code runs, the is prime function isn't automatically invoked because it's being wrapped in another function, right? Which hasn't been invoked yet. So we've just set that function up so that when it's executed it also runs the is prime function inside it. And now we can come down here and say expect and then we're going to pass in the bad call function. But we don't execute it for the same reason because it will be executed by vest itself when the test runs. But now we can add on the matcher to throw which means to throw an error and we're going to invoke it to say that we expect that when this function runs now and therefore when the is prime function runs with that string argument we expect um an error to be thrown. And if we save the file now and then open the terminal to see the test results, we should see that they all pass. But if we change the string value back to a number now like five and save the file again then we should see that this final test fails because the function now doesn't throw an error when this number gets passed into it as an argument. But we've asserted that it should do right. So let's change that number back now to a string again. And then we can save the file and close down the terminal. So then we can also make this assertion more specific by saying exactly what the error message should be when the error gets thrown. And to show you this, I'm going to copy this assertion down onto the next line. And then inside the two throw matcher, I'm going to paste in the error message that I expect this error to throw with, which is input must be a number. And that matches exactly what's written in the is prime function. So now if we save again and then open a terminal, we should see that all the tests are still passing. But if you were to change the message now from inside the function, then this test would fail. Now, I'm not going to do that right now. I'm going to leave that for you to try out on your own because I want to move on and just show you one more matcher in this lesson. So down here, I've got this final test case which says it has the correct type for the result. So basically, I'm saying I want to check the return type from the function is a boolean. Whether it's true or false, I do not mind. That all depends on the input. But in every case where we provide a valid input, it should return a boolean. So then down here I will say expect and then I'm going to pass in the is prime function and I want to call that with the number seven as an argument. And by the way, the reason we can directly invoke the function here and not before when we were checking for an error is because down here when we run the function we're just returning a value, a boolean in this case. So it doesn't really matter if the function runs ahead of time because we're asserting something on the return value. But before we weren't we were checking for an error that gets thrown inside the function. So we didn't want it to run ahead of time. Okay. Anyway, I'm going to chain on the matcher to be type of now which checks the type of the value returned from this function. And I'm going to say that it should be a boolean either true or false. Doesn't really matter which one. And before we run this, I'll quickly show you another way we can check this. So down here, let me write another assertion where we expect first of all. Then I'm going to say type of before we invoke the is prime function again. And this time we'll pass in another number for the input. It doesn't really matter which number. Now this time we're going to use the matcher to be again. And we're going to pass in the string value of boolean. So these two things essentially do the same thing just in a different order I guess. In the first line we assert something about the value returned. In the second line we get the return type first then we assert something about that. Anyway, if we save the file now and open up the terminal then fingers crossed we should see that all the tests are still passing. So then my friends there's a few different matching methods that we can use in V test to match against different values and I'm sure we're going to see more of them as we move on as well. And again, the actual things we've tested here, like the filtered array of primes or the mapped array of booleans, well, they're probably not things you would test for in a function like this. I'm just using those tests as a way to show you these different matches. So, in the next lesson, we'll get rid of all of these tests and we'll write some better ones for the is prime function. And we'll also practice with some more tests on a brand new function as
Original Description
In this Unit Testing tutorial series, you'll learn how to setup Vitest in a project, and use it to write effective unit tests for your code.
🍿👇 Get the Testing Bundle (inc Testing Next/React) for just $7:
https://netninja.dev/p/testing-bundle
🍿👇 Get early access to the course on NetNinja.dev:
https://netninja.dev/p/unit-testing-with-vitest-crash-course
🔥👇 Get access to premium courses with Net Ninja Pro:
https://netninja.dev/p/net-ninja-pro/#prosignup
🔗👇 Course files on GitHub:
https://github.com/iamshaunjp/vitest-unit-testing-tutorial
🔗👇 Vitest Docs:
https://vitest.dev/guide/
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Net Ninja · Net Ninja · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Regular Expressions (RegEx) Tutorial #14 - Matching a Username
Net Ninja
Regular Expressions (RegEx) Tutorial #15 - Email RegEx Pattern
Net Ninja
Regular Expressions (RegEx) Tutorial #16 - Finishing Touches
Net Ninja
GraphQL Tutorial #1 - Introduction to GraphQL
Net Ninja
GraphQL Tutorial #2 - A Birdseye View of GraphQL
Net Ninja
GraphQL Tutorial #3 - Project (stack) Overview
Net Ninja
GraphQL Tutorial #4 - Making Queries (front-end preview)
Net Ninja
GraphQL Tutorial #5 - Express App Setup
Net Ninja
GraphQL Tutorial #6 - Setting up GraphQL
Net Ninja
GraphQL Tutorial #7 - GraphQL Schema
Net Ninja
GraphQL Tutorial #8 - Root Query
Net Ninja
GraphQL Tutorial #9 - The Resolve Function
Net Ninja
GraphQL Tutorial #10 - Testing Queries in Graphiql
Net Ninja
GraphQL Tutorial #11 - GraphQL ID Type
Net Ninja
GraphQL Tutorial #12 - Author Type
Net Ninja
GraphQL Tutorial #13 - Type Relations
Net Ninja
GraphQL Tutorial #14 - GraphQL Lists
Net Ninja
GraphQL Tutorial #15 - More on Root Queries
Net Ninja
GraphQL Tutorial #16 - Connecting to mLab
Net Ninja
GraphQL Tutorial #17 - Mongoose Models
Net Ninja
GraphQL Tutorial #18 - Mutations
Net Ninja
GraphQL Tutorial #19 - More on Mutations
Net Ninja
GraphQL Tutorial #20 - Updating the Resolve Functions
Net Ninja
GraphQL Tutorial #21 - GraphQL NonNull
Net Ninja
GraphQL Tutorial #22 - Adding a Front-end
Net Ninja
GraphQL Tutorial #23 - Create React App
Net Ninja
GraphQL Tutorial #24 - Book List Component
Net Ninja
GraphQL Tutorial #25 - Apollo Client Setup
Net Ninja
GraphQL Tutorial #26 - Making Queries from React
Net Ninja
GraphQL Tutorial #27 - Rendering Data in a Component
Net Ninja
GraphQL Tutorial #28 - Add Book Component
Net Ninja
GraphQL Tutorial #29 - External Query File
Net Ninja
GraphQL Tutorial #30 - Updating Component State
Net Ninja
GraphQL Tutorial #31 - Composing Queries
Net Ninja
GraphQL Tutorial #32 - query variables
Net Ninja
GraphQL Tutorial #33 - Re-fetching Queries
Net Ninja
GraphQL Tutorial #34 - Book Details Component
Net Ninja
GraphQL Tutorial #36 - Styling the App
Net Ninja
GraphQL Tutorial #35 - Making a Single Query
Net Ninja
Build Apps with Vue & Firebase - Udemy Course
Net Ninja
Updated Vue & Firebase Course (Udemy)
Net Ninja
Vue & Firebase Real-time Chat (Preview) #1 - Intro
Net Ninja
Vue & Firebase Real-time Chat (Preview) #2 - Project Structure
Net Ninja
Vue & Firebase Real-time Chat (Preview) #3 - Firestore Setup
Net Ninja
Vue & Firebase Real-time Chat (Preview) #4 - Welcome Screen
Net Ninja
Vue & Firebase Real-time Chat (Preview) #5 - Props in Routes
Net Ninja
Vue & Firebase Real-time Chat (Preview) #6 - Route Guards
Net Ninja
Vue & Firebase Real-time Chat (Preview) #7 - Chat Window
Net Ninja
Vue & Firebase Real-time Chat (Preview) #8 - New Message Component
Net Ninja
Object Oriented JavaScript Tutorial #1 - Introduction
Net Ninja
Object Oriented JavaScript Tutorial #2 - Object Literals
Net Ninja
Object Oriented JavaScript Tutorial #3 - Updating Properties
Net Ninja
Object Oriented JavaScript Tutorial #4 - Classes
Net Ninja
Object Oriented JavaScript Tutorial #5 - Class Constructors
Net Ninja
Object Oriented JavaScript Tutorial #6 - Class Methods
Net Ninja
Object Oriented JavaScript Tutorial #7 - Method Chaining
Net Ninja
Object Oriented JavaScript Tutorial #8 - Class Inheritance
Net Ninja
Object Oriented JavaScript Tutorial #9 - Constructors (under the hood)
Net Ninja
Object Oriented JavaScript Tutorial #10 - Prototype
Net Ninja
Object Oriented JavaScript Tutorial #11 - Prototype Inheritance
Net Ninja
More on: Tool Use & Function Calling
View skill →Related Reads
📰
📰
📰
📰
AI Testing Tools Are Easy To Buy But Hard To Trust
Forbes Innovation
Transform Business Operations with Robotic Process Automation (RPA) Services
Medium · AI
I Didn't Expect an AI Tutor to Beat My Favorite Online Course (But It Changed How I Learn)
Dev.to AI
How to Talk to Your Database Using AI: A Practical Implementation Guide
Dev.to · Erwin Wilson Ceniza2
🎓
Tutor Explanation
DeepCamp AI