Check out a free preview of the full API Design in Node.js (using Express & Mongo) course:
The "Exercise 5 Solution" Lesson is part of the full, API Design in Node.js (using Express & Mongo) course featured in this preview video. Here's what you'd learn in this lesson:

Scott demonstrates his solution to exercise 5. He also shares a few variations of the tests since there are many ways they could be written.

Get Unlimited Access Now

Transcript from the "Exercise 5 Solution" Lesson

[00:00:00]
>> [MUSIC]

[00:00:03]
>> Speaker 1: So I am aware that there going to be tons of differences of how people test this. This is great. There’s so many way you can do it. Some people started using before, before each and maybe even after each and some people use promises. Some people made multiple requests inside of one id block, some people did method describes or many describes.

[00:00:26] So there's so many ways you can do this. There's not one right way to write these tests. So I'm going to show you the solution I have which probably is not one of the best ways but let me start this or commit this actually.
>> Speaker 1: All right, so, let's see, checkout.

[00:00:49] Step-5-fix. So the way I wrote it was, I just did nested requests for things that need a resource to be there already. So as far as creating a line, the way I created a line is, well this one was pretty easy to just create a line. So you make a post request, if you didn't find out, you have to use the .send method.

[00:01:18] You can send json to the request. I'm just putting in a line here. Mufasa, evil lions. And then application json expected 201. If you put 201, or if you put 200 and you got back a 201 and still passed, that's fine because they're both passing status codes. If you did something like 400 or something, you're not supposed to change it.

[00:01:42] And then inside of here I'm just doing a basic type test. So expect this to be an object. So really again, silly test. You could probably write better tests than this and you should, but again this is just an example of how you would write tests. So for instance, you would write tests to see like, expect, or first I'll say var lion or Mufasa.

[00:02:11] Is that how you spell his name, Mufasa? Whatever, I don't think anybody knows how to spell his name.
>> Speaker 1: And then you just say
>> Speaker 1: Mufasa.name to be, so these are better tests right. You actually like make sure that this stuff is the way it should be, or you can just do like equality check so you can say expect Mufasa to be like, make this object somewhere else.

[00:02:51] Bar line equals stat. Then come down here and say send the lion, and then expect Mufasa to equal, this is deep equal lion. So then we check and see if the objects are the same, right.
>> Speaker 1: if you use eql, that won't work cuz it'll literally do object equals object which is false.

[00:03:30] They're two different objects. They're both objects, but they're two different objects so that would work. Where as eql would do a equals which means like just check to see if they all have the same properties and same values. So you would run that. You can just run epm test to run test.

[00:03:52] I guess I didn't update [INAUDIBLE] this one. [INAUDIBLE] let me see. Yeah, so thepackage.json if you just, the test script you can say, what you would normally put which would be mochaserverspec.js and run that [INAUDIBLE] test. It looks, like the ID is wrong. Yeah, the ID is wrong because it gets changed to a number on the server.

[00:04:17] So, I guess that really wouldn't work?
>> Speaker 1: So, I'm just gonna get rid of that one for now. And then as far as deleting a line.
>> Speaker 1: We need a lion there in the first place. So I guess technically we do have one, because we just posted to the server.

[00:04:41] That's great, but I don't have this lion's ID. I didn't save it because first of all it's in this it block up here so I don't have Mufasa.id. I need that ID to send a request although, we can probably assume it's just one because of the first one.

[00:04:56] So, we can just put one there, which is okay but, it would be better if we had the ID. So, what I did first was I made a new lion. I'm like, all right, so I sent the lion there. And on that response, grab the lion then do another request that deletes what that lions ID.

[00:05:14] And I'm just going to expect the rest of that body to d equals the lion that I sent.
>> Speaker 1: Which would probably fail too because the ID. It passed. Everybody see me there? I just made a request, I created one first, I got the id of it, and I sent it.

[00:05:42] The other way you could do it is you could do it before. So like in mocha and jasmine, inside of a describe you can use before and before each and the way this works is it's a callback function that will run either before all the its, or before each it depending if you use before or before each.

[00:06:02] So I could say before each it just go ahead and make a new line right. So I could just make a new line here but then I have to play with the closers a little bit, because I need to be able to reference that lion. So I need to say, created lion and then down here I have to update it every time.

[00:06:21] I don't like messing around with closers so I decided not to do that. Any questions so far?
>> Speaker 2: A couple came up here. How would you do some negative integration testing? Negative integration testing. I'm not sure exactly what that is. That's the first time I've ever heard negative integrating testing.

[00:06:44]
>> Speaker 1: I'll see if they're a couple of seconds.
>> Speaker 2: All right.
>> Speaker 1: I'll see if he adds to that.
>> Speaker 2: Okay. Any other questions?
>> Speaker 1: I guess for like fail request failing.
>> Speaker 2: If request failing?
>> Speaker 1: Or name no longer equals after update. So, I’m still not quite sure, but I'm guessing what he's saying if for instance you were testing to see if this user had access to this url, you expect it to come back as a 401, or something like that, then yeah, you would just type in the appropriate status code.

[00:07:19] And then you would just do some assertions on the response that your server sent back. So if you were trying to access this resource and you expected to get a 401, and you expected to get this certain error message back, it's the same thing. I mean, it's no different.

[00:07:32] It's the exact same thing. You just have to make sure you expect the assertions that your server is sending back. It's no different.
>> Speaker 1: Any other questions?
>> Speaker 2: I'm caught up here.
>> Speaker 1: Okay.
>> Speaker 1: That was delete. The update is pretty much the same thing. You need to create a line, grab the ID, and then you also need to send an object to update something.

[00:08:04] So I sent an object, just updating the new name. And now we just wanna make sure that the new name got updated when it came back which it did rIght? So created a line with the name called test lion and then when that came back I grabbed that lion's ID and then I wanted to update it with a new name, that's called new name.

[00:08:24] And then when that comes back I'm gonna inspect to see that it equals the new name.
>> Speaker 1: All right. Any questions on that?
>> Speaker 2: What about testing preconditions, like checking that the lion exists before deletion?
>> Speaker 1: Checking the lion exists before deletion. So let me walk through that.

[00:08:56] So let's go back to deletion. So here we deleted it. We want to see if the lion exists before delete. Well, so we posted the server and we created a lion. We have the lion, and then we deleted it. So, I mean, you mean testing this lion right here?

[00:09:13] I think that's what he's talking about. I mean, yeah, you could test this line, but this test is not for creation, this test is for deletion. That’s why I didn't make the assertions here. I think that's what the person's talking about. I'm not sure.
>> Speaker 1: But we're just testing whatever the server response is.

[00:09:31] If you want to be able to test more things, then as far as integration tests go, you're only gonna be able to test whatever the server responds to you. If you want more fine-grained control of what's actually happening, then you have to write unit tests.
>> Speaker 1: In the update task [INAUDIBLE].

[00:10:00]
>> Speaker 1: Now I made a put, so in the update, I made a host to create the lion and then down below here I made a put request to update the lion.
>> Speaker 2: There's a question [INAUDIBLE], can they have, can you have a function that runs before any test?

[00:10:23]
>> Speaker 1: Yeah, you can have, so all you have to do is go to the top. Describe in your test and put it beforeEach. So I put beforeEach here. This will run before every single it. All right so if I say console.log right here,
>> Speaker 1: Then I go run my test.

[00:10:42] That should run before every single it. Yup, hey hey hey hey. So let's go to your top scope and do it before each.
>> Speaker 1: Cool. It looks like I forgot one. I get 1, right? Should be a test for a get 1. Yeah, but that was pretty remedial.

[00:11:15] I could write it, but I'm not gonna write it unless people want to see me write it. It's just going to be the same thing as get all. It's gonna be like create one and then get one. I can do it, but I think you guys get the point.