API Design in Node.js, v5

Testing Helper Functions

Scott Moss
Netflix
API Design in Node.js, v5

Lesson Description

The "Testing Helper Functions" Lesson is part of the full, API Design in Node.js, v5 course featured in this preview video. Here's what you'd learn in this lesson:

Scott demonstrates dropping and recreating tables in tests to ensure a consistent starting state and catch schema-related bugs early. He also creates helper functions for tasks like adding test users or habits and cleaning up data efficiently.

Preview
Close

Transcript from the "Testing Helper Functions" Lesson

[00:00:00]
>> Scott Moss: Why do we drop and recreate tables? Well, kinda like what I told you. I want each test to have the same state as all the other tests, so I wanna drop everything, make sure there's no leftover data from the previous test runs, you know, have a consistent starting state, and catch schema related bugs early on, not during the test, so. Yeah, that's why we're doing that, and then now we just need to make some of our database, helper functions.

[00:00:17]
Yeah, that's why we're doing that, and then now we just need to make some of our database, helper functions. These are helper functions that are gonna help us like make mock data like. You know, putting a user in a database or creating a token or creating a habit, things that we'll use, inside of our test to get things done, that makes sense? Otherwise I have to rewrite this stuff every single time, so.

[00:00:31]
Otherwise I have to rewrite this stuff every single time, so. Let's do that. So for the helper functions Pretty straightforward. We'll just Go into the same.

[00:00:51]
We'll just Go into the same. Wait, why did this put this here? How did, how did this not get in the test folder? What's going on?

[00:01:14]
What's going on? Oh, OK, I must say dragged the wrong thing. Hold on. Get it.

[00:01:27]
Get it. There we go. OK. That's good now.

[00:01:42]
That's good now. I must say all these paths are gonna be broken, but it just auto fixed it. I kind of like one that works. OK.

[00:02:02]
OK. So yeah, same thing inside of test setup, we wanna add another file. And we want to call it DB helpers dot ts. And it's like this file again, it's just it's just it's almost like the seed script really, it's just a bunch of helpers.

[00:02:22]
And it's like this file again, it's just it's just it's almost like the seed script really, it's just a bunch of helpers. That we can use to Interact with the database a lot easier inside of our test versus having to write this logic all over again, so. We're gonna write some tests for users, habits maybe and entries. I should probably just do some for habits since that's the only one we did Routes for.

[00:02:42]
I should probably just do some for habits since that's the only one we did Routes for. And then You want to get the source DB. Schema we wanna get. Hash password from there cause we're gonna use that, or maybe not probably not gonna user stuff, but it's OK.

[00:02:57]
Hash password from there cause we're gonna use that, or maybe not probably not gonna user stuff, but it's OK. And then generate. Token from there. Cool, OK.

[00:03:16]
Cool, OK. So the first thing is, we want a function that we can call. That will create a test user for us that we can then use inside of our test because almost everything is gonna revolve around the user so let's just go ahead and make a function that creates that test user so const or export const create test user Async. You can pass in some stuff to override it if you want.

[00:03:30]
You can pass in some stuff to override it if you want. And this is where like you could do like a partial thing if you want, so you technically could do something like. You say like partial, and then you can put in a. New user like that, you do that?

[00:03:52]
New user like that, you do that? Versus having to like write it all out and then that way everything is optional even though email username and password. But by default, what we'll do is we'll just say. It's an empty object.

[00:04:10]
It's an empty object. You didn't give us anything. Cool. So now I can say cool, default data for a user assuming you gave us nothing is all of this stuff, so email would just be test.

[00:04:36]
So now I can say cool, default data for a user assuming you gave us nothing is all of this stuff, so email would just be test. Right, and I need to make this unique, so best way to make something unique is either math dot random or a date, so I'll see. They got now. Minus Math dot random.

[00:04:54]
Minus Math dot random. Like this. At Example.com Cool, now we have hopefully emails that don't conflict with each other, username. Yes test user.

[00:05:11]
Yes test user. And you can put whatever you want here, pretty much just gonna do the same thing. It's gotta be oops. Date dot now.

[00:05:32]
Date dot now. Minus math dot random. Cool, that's the username, password, doesn't matter if these are the same, so we're good here. Best password in the world, first name is Test, last name is user.

[00:05:54]
Best password in the world, first name is Test, last name is user. And then any other user data that you might have passed it. Which will override anything that we offer. So Next thing I would do is I need to hash the password for whatever password is in here, cause we don't save.

[00:06:25]
So Next thing I would do is I need to hash the password for whatever password is in here, cause we don't save. Plain text passwords, and if we test any of that all stuff, it would break if we didn't hash this passwords, so we'll go ahead and do that. Say default data that password, get that hash password, and then let's make a new user, so. Await, DB and you might ask why don't just use like some other thing somewhere like in a controller to create the user?

[00:06:52]
Await, DB and you might ask why don't just use like some other thing somewhere like in a controller to create the user? Well, I'm probably, I'm writing test to test that so I couldn't use it in here in my function. I'm gonna use for test, so I have to write it over. This is code that probably won't be tested because it's using it's to support test so.

[00:07:14]
This is code that probably won't be tested because it's using it's to support test so. dot values. Default data. Password is the hash password.

[00:07:35]
Password is the hash password. Cool. Start returning, get that user back. There we go.

[00:07:53]
There we go. Create a token. And that's just gonna be generate token, pretty much what we did before we got our ID which is our user. Dot ID our email.

[00:08:04]
Dot ID our email. And our, Username. Cool. There's our token.

[00:08:21]
There's our token. And then we just wanna return the token. The user, and then the raw original password if you're gonna try logging in. Cool, so that's our helper function to create a user.

[00:08:44]
Cool, so that's our helper function to create a user. Now we just want to write a helper function to create a habit, so let's do that. Got that. This is just going to take in, you know, pretty much something similar.

[00:09:03]
This is just going to take in, you know, pretty much something similar. We got a User ID cause all habits can't be created without that, and then we have habit data. Which again is a partial. Do I have an insert for a habit down here, let's see.

[00:09:28]
Do I have an insert for a habit down here, let's see. This is inferSelect, so I'll make one for infer Insert, I'll call it a new habit, and it will be. inferInsert. So now we have a new habit type that I can use.

[00:09:56]
So now we have a new habit type that I can use. In here, I can say new. habit. Here we go.

[00:09:56]
Here we go. So now we have our habit data. And this is going to take Oh yeah, we need to default to empty object. There we go.

[00:09:56]
There we go. So then we're gonna do the same thing, default data, it's gonna be some object, we're gonna give it a name. We're gonna say this is a test. Habits Like this.

[00:09:56]
Habits Like this. Collision free. But the date of now. And then we have our description, if we want to do that as a default.

[00:09:56]
And then we have our description, if we want to do that as a default. Like you say a test habit. And then we want to add a frequency if we want to here. And then we can do a target count, whatever we want.

[00:09:56]
And then we can do a target count, whatever we want. Here we go, and then. Have a data spread across to override all of our potential defaults. Like a habit.

[00:09:56]
Like a habit. Insert into the habits. With these values. The User ID of being that and then whatever that default data is returning.

[00:09:56]
The User ID of being that and then whatever that default data is returning. And now we have our habit. Cool. And lastly, just a program programmatic way to clean up the Databases.

[00:09:56]
And lastly, just a program programmatic way to clean up the Databases. Clean up database. This would just be await DB. Delete Entries.

[00:09:56]
Delete Entries. Db dot delete Habits Users Tag. HabitTags. Cool.

[00:09:56]
Cool. All right. Those are all of our helpers.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now