First unit test
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 Pain Free Mocking with Jest course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Pain Free Mocking with Jest, plus 70+ \newline books, guides and courses with the \newline Pro subscription.
[00:00 - 00:13] In this lesson, we'll learn the basics of writing unit tests using the it or test functions provided by Jest. And following the arrange_act_asset_pattern, we'll write a unit test for its password correct.
[00:14 - 00:22] A function that verifies if a password is equal to a hash string. This is part of the basic units we'll use to create our login feature.
[00:23 - 00:32] In module 1, we set up our development environment which included installing J est. In this lesson, we'll write an actual test for a unit that we'll create.
[00:33 - 00:40] Head over to your code editor and let's write some tests. In the source folder, create a subfolder titled "Services".
[00:41 - 01:16] In this new services folder, go ahead and create a new file and name it user service.js. This file will contain methods that perform different user specific tasks, such also export it.
[01:17 - 01:48] as checking if an email exists if a user's password is correct, etc. Before we proceed any further, we need to install a dependency bcrypt. Open your terminal and run this command.
[01:49 - 02:17] Now let's import bcrypt in our user service.js file. The password "correct" function is to have two parameters, the password string and the hash string.
[02:18 - 02:33] The compare method returns a promise so we need to use our wait here. And to also do that, we need to make this function an asynchronous function.
[02:34 - 02:42] Lastly, we return the result of bcrypt.compare method. Now let's write a test for this function.
[02:43 - 03:02] In our test folder, create a new directory called "Services". And in this services folder, create a new file, user service.test.js.
[03:03 - 03:12] Before we create a test, let's quickly discuss the two flavors that just supports. When writing testing, just we use the "it" or "test" functions.
[03:13 - 03:25] While both of these functions serve the same purpose in writing test cases, they have subtle differences. The "it" function is closely related and often used with behavior-driven development BDD.
[03:26 - 03:41] A "practice that emphasizes communication and shared understanding of requirements between software developers, business stakeholders and testers. The "it" function is more descriptive emphasizing the specific behavior being tested.
[03:42 - 03:53] On the other hand, the "test" function is more generic and functional. Both "it" and "test" functions accept a string describing the test and a function containing the actual test logic.
[03:54 - 04:06] It's important to note that both can coexist in your codebase, but I strongly advise choosing one and using it consistently in your codebase. In our user service.test.js, our created basic test using the "it" function.
[04:07 - 04:12] The "it" function accepts two parameters. The first is a string and the second is a function.
[04:13 - 04:20] To better understand how we can properly name our tests, let's review some patterns. I'm only used in naming tests.
[04:21 - 04:30] The first approach is the "given, when and then" framework. This is borrowed from BDD, behavior-driven development and helps to structure your test based on user stories.
[04:31 - 04:37] It follows a clear flow. The "given" part describes the initial state of your system and any setup required.
[04:38 - 04:50] The "when" part describes the action taken by the user or the code on the test. And the "then" part describes the expected outcome or system behavior after the action.
[04:51 - 05:03] An example would be "given, correct password and hash" is password-correct function returns true. The second approach is the "use naming" and this approach focuses on three key aspects.
[05:04 - 05:13] The unit under "test" which identifies the specific code being tested. A scenario which describes the scenario or inputs to the unit.
[05:14 - 05:24] And the "expectation" part which states the expected outcome after executing the code. An example of this would be "is password-correct" given "correct password returns true".
[05:25 - 05:48] Let's head back to Visual Studio Code and properly name our test using the "use naming" framework. The next thing we need to do is add the test logic in the function.
[05:49 - 06:02] To structure our unit test we follow the "arrange, act, assert" pattern. This pattern helps us to setup the necessary conditions, perform the actions we want to test and then verify the expected outcome.
[06:03 - 06:11] In the "arrange" part I will create a hash. In the "act" part I will call the "is password-correct" function and then pass the "password string" and "hash".
[06:12 - 06:18] Lastly we need to make an assertion. In the "arrange" step we setup the necessary conditions for the test here.
[06:19 - 06:26] We define the "imput string" and "hash". Next in the "act" step we will call the "is password" function with the "imputs " values.
[06:27 - 06:35] Finally in the "asset" step we verify the expected outcome. In this case we assess that the result of the function is true.
[06:36 - 06:49] Now let us write another unit test for the "sad" part where the password is incorrect. In this case I will use the "test" function just so we see that both the test and its functions can coexist in your codebase.
[06:50 - 07:05] Similarly in the "arrange" step we setup the necessary conditions for defining the "imputs string" and "hash". In the "act" step we call the "is password-correct" function with the "imputs" values but in this case a "wrong" password.
[07:06 - 07:13] Finally in the "asset" step we verify the expected outcome. In this case we assess that the result of the function is false.
[07:14 - 07:45] Now let's run these tests. [silence] You have learned how to write your first unit test using the "it" and "test" functions and following the "arrange" "act" asset patterns.
[07:46 - 07:55] By writing tests that cover both the "happy" and "sad" parts we can ensure that our code behaves correctly in different scenarios. See you in the next lesson.