Check out a free preview of the full REST & GraphQL API Design in Node.js, v2 (using Express & MongoDB) course:
The "Writing Tests" Lesson is part of the full, REST & GraphQL API Design in Node.js, v2 (using Express & MongoDB) course featured in this preview video. Here's what you'd learn in this lesson:

How to code out unit tests using mocha and chai. - https://github.com/FrontendMasters/api-design-node-v2/tree/lesson-8

Get Unlimited Access Now

Transcript from the "Writing Tests" Lesson

[00:00:00]
>> Scott Moss: We've got one more thing today. This one's not so much of a lesson but just an exercise. And in fact, there really is no solution to it. It's just something that you should do. And you could probably do it for homework if you want. I could go over the solution, but just like I said, there's not really a solution, I guess there is but not really.

[00:00:19] But anyway, what we're gonna do now is we're gonna write more test. Remember when I said for the API we're only testing if it get all for GET impulse and there's four other methods for each resource, we're not writing tests for that. This is where you write tests for that.

[00:00:33] So these tests right here are generated tests, you can see we're doing some metaprogram here where these tests take any model or resource name. And what a new resource of that will look like and it generates test. It generates the get all tests, it generates the post test, it generates all that stuff for every single models.

[00:00:51] So these tests are generic enough to work for all of the models and resources, that's how well our code is right now. We can generalize our test and it still works. And you might say, well, if that's the case and I wrote test for one of them why do I need to test all of them?

[00:01:06] Well, just to make sure nobody changed or added anything extra in between your metaprogramming and the result. So we would need to write tests for, as you can see for now, we're writing tests for GET and POST. But for GET, we're only testing if you can get all.

[00:01:19] We need to test if you can get one. What you need to do is to create one first. And then for POST, we're only testing if you can create one, which is all post can do. But we also need to test for put and delete.
>> Scott Moss: So let's just write one right now, let's just write the one for get one, cuz this one's kinda hard as you need to create one before you can get one.

[00:01:40] So we just say it('should get one $(resourceName) is.
>> Scott Moss: And this is gonna be async, you can also just return a promise if you don't wanna use async.
>> Scott Moss: Let's do that. And then basically this is testing that we can actually use the get one API call, actually get one from the database, right?

[00:02:03] So what we need to do is first we need to create something in the database, so we'll just go ahead and create in the resource. And we'll say newDoc =, whatever that model in that was passed in, right here, model. So model.create() and we'll say, bless you. You could take in this newResource object which will be what you need to create that new resource.

[00:02:27] So model.create(newResource) and we'll await that. And then now we have that, we can go ahead and issue our API request. I'm just gonna copy this.
>> Scott Moss: Paste it here, so we can use, whoever has used Chai before inside of Mocha? Awesome, so they have chai.request, which is basically a wrapper around SuperTest, you ever hear of SuperTest or SuperAgent?

[00:02:51] Okay, all it is is just a HTTP mocking suite, that's all it is. SuperTest is like it basically allows you to make assertions against an HTTP call. So you can make an HTTP call, come back, and do the searches against its headers, its status codes, its response. And what Chai did?

[00:03:09] Chai is an assertion library for JavaScript. They made a wrapper around it that you can hook Chai right into. So we're using Mocha to test, and we're using Chai for assertions. So chai.request is just a wrapper around SuperTest, which is just a wrapper around making a searches around HTTP requests.

[00:03:28] So it's a lot of abstractions tied into each other, by the end of the day, we're able to make a request. And we can run assertions on that request. For instance, I made the request, stored into the result, and I can check that that result as a status of 200.

[00:03:43] I can check that the result is JSON, stuff like that. So we're gonna do the same thing. So I'm gonna say okay, await chai.request, api/$(resourceName), for GET. Well, this is get one, so I need to put an ID here. The ID is gonna be whatever newDoc.id is. And then, I need to set authorization because authorization is on by default.

[00:04:08] So this jwt right here is generated for your above, so you don't have to worry about it. And then now that that's there, I'll grab the result, and then I'm gonna do some assertions on it. So if I did a update, or I'm sorry, I'm doing a get one, I expect that the results to be very similar to this newDoc right here.

[00:04:27] Because this newDoc is the creation, and now I'm doing a get one to actually get that newDoc, so they should be very similar. So we'll run these. I'm gonna console.log the results so I can see what the body looks like.
>> Scott Moss: And we'll put a .only here to only run this block.

[00:04:46] And then we'll test our code. Go away.
>> Scott Moss: Cool, so it looks like it worked. Wow, what? Yeah, it logged one for every single one. So we get a response, which is this huge thing. Really all I want is the body. Well, basically, that's gonna be our test.

[00:05:10] This one should be passing. We need to write more granular test, check to make sure the thing that's coming back is actually the thing have some of the property of it right now. But you can see, that's passing. That one test that I wrote right here, generated three tests, cuz it made it for each model.

[00:05:25] Each model is using this. So you can see, it generated a GET /playlist, GET /song, GET /user for each one. And it's actually gonna be called, yeah, get resourceName, yeah. So you can see it's working pretty good. Should get one song, should get one user, should get one playlist.

[00:05:45]
>> Scott Moss: And then you would do the same thing for updating one and deleting one.
>> Scott Moss: And you would do that down here.