No video
Testing Express REST API With Jest & Supertest
Repository: github.com/Tom...
❤️Host your applications and get 💰$100 credit (referral): m.do.co/c/1b74...
📚 Concepts & technologies covered
- Testing a REST API end-to-end with Supertest & mongodb-memory-server
- Mocking services
- Testing from the controller to the service
🌎 Follow me here:
Discord: / discord
Twitter: / tomdoes_tech
Facebook: / tomdoestech
Instagram: / tomdoestech
TikTok: / tomdoes_tech
☕ Buy me a coffee: www.buymeacoff...
Пікірлер: 110
1. 0:00 - Intro 2. 2:00 - Getting started & Setup 3. 5:10 - Creating test file for 'products' 4. 8:06 - Adding test command and running it 5. 9:24 - Refactoring in order to implement supertest 6. 15:50 - mongodb-memory-server (Author recommends mocking the service instead, this is demonstrated in chapter 10. ) 7. 18:47 - Adding more tests 8. 25:22 - JWT 9. 29:54 - .skip and .only flags for jest 10. 30:54 - Test file for 'Users' (The authors recommended way: mocking out service instead of mongodb-memory-server) 11. 36:26 - Mocking out and 'spying on' userService 12. 41:27 - Running the first User test 13. 43:57 - Clearing mocks in between tests 14. 46:05 - Reseting mocks in between tests 15. 47:16 - Test creation of user access token (Last test in the tutorial) 16. 52:34 - Bonus: Jest extension for VSCode
This channel is a gem! I appreciate that you cover important and practical topics (i.e testing, TS) in great detail. I've seen some videos on the 2 topics mentioned above but not as as it pertains to Nodejs. Thank you and you definitely deserve more views/subscribers.
Best tutorial on KZread so far... and I've been searching for months
I'm really greatful for such tutorial. Before knowing about all taht stuuf, I asked myself : "How cna I test my API efficiently, with the most detailed tests possible and reproductibility ?". I almost started to cre&te tests using bash & curl, and starting my server as a daemon. I knew it was not the solution, so I didn't started yet. Thanks to your video, I know the correct way now.
THANK YOU SO MUCH for making this video. I've been looking for a compare and contrast of mongo-memory-server and mocking services for quite awhile!
Thank you very much, this is exactly what I need for my practice :> There are extremely few videos about Jest comparing to Cypess. Luckily I found yours :>
This is the best tutorial ever, thank you Tom!
I am so genuinely excited for this you sir are a beacon of light in the coding world lol starting it now👌🏽💯
@TomDoesTech
2 жыл бұрын
That's really kind of you, even if it is a little odd :)
I was absolutely clueless on how to mock my own functions. thank you so much
Thank you so much man, learning alot from you.
This video is exacly what I need ATM. ChaiHttp just decided to stop working, also it have problems with ES6 import modules, so I really needed to learn how to use Supertest, also I learned a lot of good practices in this video. Dude, this video is a complete GOLD.
I really like your use of multiple describe blocks here. I recently implemented something very similar for a project and have found having these tests is really helpful when refactoring. Thanks for the content!
@TomDoesTech
2 жыл бұрын
Thank you :) I was a bit nervous about doing that in this tutorial because I didn't want to turn anyone off, but it's how I structure my tests and I find it really valuable.
This series is the best tutorial I've been following, thank you very much it is gold
@TomDoesTech
2 жыл бұрын
Thank you so much! That's really kind of you.
Hi Tom! Your authentication API video with typegoose and zod helped me tremendously. I know i will learn a lot from this, so Thank you for making this video!
Thanks for the awesom video. You made my TDD weekend fun.
This is awesome that your are expanding the same API. I hope this series keeps going!
@TomDoesTech
2 жыл бұрын
Yeah, going to build a UI next to show how to use the access & refresh tokens.
Thanks for your efforts Tom. Love the video
Great testing video. Appreciate your time and effort with it. Found your channel a few weeks ago and have slowly been making my way through all the videos. :)
@TomDoesTech
2 жыл бұрын
Thanks Chris! Glad you're enjoying the videos. Feel free to jump on the Discord server if you have any questions.
Ooooo man. Don't miss even 10 seconds of this video (13:30 - 13:40). I missed the movement of `routes(app);` from ./app.ts to ./utils/server.ts and for 90 minutes was questioning my sanity as the API worked but the tests that exercised the route didn't. Because without this step, you get a 404 error by default for calling a route that doesn't exist - exactly the response code needed to pass the first product unit test - and the second unit test will never pass whatever you do.
Amazing tutorials as always, love your Typescript/Mongoose/Express series
@mystik5551
2 жыл бұрын
now a curious to see
Thanks you so much this video helped me a lot in braking the code and testing .
@TomDoesTech
2 жыл бұрын
Glad it helped!
Hi Tom, thanks for the video. With the updated repo, if you follow along to the video you will find that you will not be able to get most of the mongodb-memory-server section to work. 1. You will not be able to get product.productId after calling createProduct because productId doesn't exist in either the ProductDocument or ProductInput interface. To fix this I had to put productId: String in the ProductDocument interface, not sure if that is the right approach but the tests passed after that 2. You will not be able to use signJwt because it expects 2 parameters now, not sure how to get around this one. I skimmed through the rest of the video and didn't see any fixes for that so I stopped trying here.
Thanks!
Good video! I watched it for the second time.
Didn't watch the whole video, but was wondering if you do unit tests in the video?
.set('Authorization', `Bearer ${jwt}`) not working any idea why?
For current versions of jsonwebtoken error `Error: secretOrPrivateKey must be an asymmetric key when using ES256` could be solved by adding `allowInsecureKeySizes: true,` option to signJwt function. Cheers.
really helpful and fun, thank you.
When deploying the website should I also upload the test?
Thank you. Any video for complex json object test cases scripts example in jest?
awesome video on testing with Jest
is it possible for someone to replace where we used mongodb-memory-server with the real MongoDB server?
Hello, thanks a lot for this tuto! I have a problem with using the send method for a post/put request, I always get an error "Right-hand side of 'instanceof' is not callable" What is the reason of this error?
Excellent ! Thank you so much
Great video one of the best!
Late comment but for some reason Jest times out when i'm running all of the test after I included the "should return a 200 and create the product"... but if I just run that test individually with '.only' then it doesnt time out and passes. I even tried extending the time but it still times out when running all of the tests.
can you please tell me which vs code extension you are using for highlighting the code block
Even if I mock the service for user it still calls mongodb and creates it in database. Any thoughts?
When testing api with ject, do you actually need to have data in database?
is jest used in this video . what is the difference between jest and supertest ?
@TomDoesTech
10 ай бұрын
Yes, supertest is for sending HTTP requests in your tests
great job.... thx
great tutorial keep it up but why did you need ts-ignore on the mockReturnValue?
@demamdq2346
Жыл бұрын
because the service function that we are mocking are async and they return a Promise, and in jest we are saying that it will return a Product. So typescript is saying , that the return type is not the correct one.
Which extension are you using to get "intellisense"-isc behaviour in the terminal? And also which extension to get the "Run | Debug" options over each "Describe"-block?
@TomDoesTech
Жыл бұрын
It's an autocomplete plugin for zsh
This is awesome!!! thank you for this lesson. One request, can we make it a full stack app i.e. can we build a frontend to consume this API? thank you once again.
Nice video. I got a problem with this, inside config folder, test.ts file have the private key, if I remove the private key from test.ts file config and create the custom-environment-variables.ts file to read the variable from an env file, it doesn't work because can't read the private key value, if I just paste the private key into the test.ts file all work again, any idea or config I am missing there?
@TomDoesTech
2 жыл бұрын
If your problem is that it can't get the value when you're running the tests, it's because you haven't called dotenv.config() before running the tests. You should be able to add it to a script that runs before your tests run. Otherwise, just generate some public and private keys that you use for tests and put them in test.ts
@LuisAlbertoSandovalArevalo
2 жыл бұрын
@@TomDoesTech oh yeah, that was my problem, the dotenv.config() call, I used that on a file that call the one I was testing, but not on the actual file. Thanks
Hi Tom, first of all thank you for your dedication for wanting to help others. I wanted to ask you how would I do the same with testing the endpoint only, without controllers and services?
@TomDoesTech
2 жыл бұрын
Why would you want to test the endpoint? You could mock the controller and asset that it was called with the expected request and response objects.
@arberi99
2 жыл бұрын
@@TomDoesTech The endpoint has the logic inside, it's not split with controllers, so the logic is declared on the POST request (e.g signing up a user with jwt middleware) and returning a token. Its all inside the routes folder.
@TomDoesTech
2 жыл бұрын
@@arberi99 Do it exactly the same as I did it in the video. Tests should care about implementation, all they should care about is that given X input, Y should happen or Y should be returned, how your function does that shouldn't have anything to do with the test. Having said that, split your code up a bit and it will make your life easier. Check the video before this one to see how I did it: kzread.info/dash/bejne/dIuJy5h7g5y6Zbw.html
which terminal you are using in VSCode?
Hi, great video. I have a question tho, how do I mock a class service?
@TomDoesTech
Жыл бұрын
Just mock it like it's a function, because that's what it is
@neghidev
Жыл бұрын
@@TomDoesTech Ok, thank you very much
awesome tutorial🤌
do we learn UNIT testing here?
Hi! Great tutorial! Just wanted to ask what file icon theme are you using on vscode? thank you!
@TomDoesTech
2 жыл бұрын
I think it's just the default theme
@osemudiamhen
2 жыл бұрын
@@TomDoesTech okay thank you!
you didnt explain clearly what is the difference between clearMocks and resetMocks? and what is the difference between supertest and plain axios?
@TomDoesTech
2 жыл бұрын
Read the docs if the explanation wasn't clear enough. Supertest will start an instance of your application and run requests against it. Axios will just send a request to a given URL.
Thanks you so much 👍🏼🎉🙏
Thanks sir 😊
@41:10 line 6, const app = createApp(), createApp() is not defined.
@TomDoesTech
2 жыл бұрын
Di you watch the part where I refactored the app?
Good content, but it's honestly really hard to watch, with everything jumping around on the screen. So please consider this, because it's really not easy on the eyes to consume your content, and it's hard to stay focused. I haven't noticed that in your other videos though as much, but this one is kinda tough I still hit that like button though, because there's still value in the video
I keep getting "TypeError: (0 , supertest_1.default) is not a function." What's the problem here?
@TomDoesTech
2 жыл бұрын
Try importing supertest like `import * as supertest from 'supertest'`
@tylerwong3290
2 жыл бұрын
@@TomDoesTech It worked thank you!
I didn't enjoy this video as much as the last one the explanations were too brief it felt like you were just rushing true it also I did not really understand that last test so well. i don't have much experience in testing so maybe that is the problem. looking forward to the next video in the series. Thank you Tom.
Awesome Tutorial +++++++++++++++ Thank you.
do you have a video with javascript and not typescript?
@TomDoesTech
Жыл бұрын
Nope
Please show us how to make the React front end to this API
@TomDoesTech
2 жыл бұрын
Hey Mohamed, thank you for your kind comments. The video you're after is here: kzread.info/dash/bejne/oYeulJWpgKXWdrw.html Then you may want to add Google OAuth: kzread.info/dash/bejne/g6hnrayTYs63m5M.html
tldr version??
You're awesome!
Are these tests considered unit-tests or integration tests? I'm leaning towards unit-tests since there is not really a database interaction and you are only mocking a service. But what if in the service you make a call to the database and fetch some data, is it considered to be an integration test then?
@StringSwoosh
2 жыл бұрын
Nice video btw! Wrote my first nodejs (ts) tests!
@TomDoesTech
2 жыл бұрын
You could argue for both, they test across multiple units of code, but I'd they say are unit tests. Don't get too wrapped up in what a test is called, be more concerned with how it makes your software more reliable.
@StringSwoosh
2 жыл бұрын
@@TomDoesTech thats what I’m thinking as well, but for my assignment I need to get the correct definition. If I describe it like that I think it will be sufficient enough. Thanks for the vid 👍
@nathanielkhallil9222
Жыл бұрын
@@TomDoesTech While I do find this a confusing subject when it comes to end points and especially databases, it's to my understanding that if one were to mock the database or API in any fashion that means disconnecting the reliance on another component to be functioning properly in order for a test to pass, it's a unit test. The reverse being an integration test when the code tests multiple aspects of the program at the same time; i.e. we write a test that connects to express which in turn runs a function that connects to a database and creates or modifies or deletes a user for example. The only confusion I have there is when we also consider end-to-end or end point testing which more or less involves connecting to say a page route, but does not involve connection to a database or other component? I find this especially confusing when using a template engine like .ejs where even a basic rout to get a page might also be required to render dynamic data. I suppose I could just write the tests to ignore the dynamic data aspect, focusing only on reaching status 200 or 302 for rerouting. On a different note, I found in my current project that jest loved to assume the server was open even when it should be closing since I separated my server listen from the app just like you did here with server.js - importing the server separately. let serverListen // teardown beforeEach(() => { serverListen = require("../server.js"); }); afterEach(() => { serverListen.close(); }); I found this little bit of code resolved the warning. I was running quite a few tests concurrently and solved those by changing serverListen = require("../server.js") to a specific port for each test file serverListen = app.listen("5006"). This was NOT always necessary, I just found it solved issues where one of my test suites would "butt heads" with another on and off. Great video overall. Good mocking content is actually tough to find in Javascript and since I am new, there's an amazon aws-sdk mocking issue driving me nuts atm hahaha. (I REALLY need to learn typescript and c#) >_
● Validation Error: Preset ts-jest not found. Configuration Documentation: jestjs.io/docs/configuration if ANYONE face this error, remove the present in jest.config.js file
@ricardorien
Жыл бұрын
anoying issue
@ricardorien
Жыл бұрын
Bro, no you have to instal ts-jest as a dependency: for example: yarn add ts-jest -D
Thanks very much, great video. When testing 'user registration' for 'given username and password are valid', I kept getting a 'TypeError' => 'user.toJson is not a function' in the referencing user.controller.. I removed the toJson() from the omit function and test passed and the route still works without. Couldn't quite understand what the issue was? Testing removing toJson from the omit functions in user.service, the app broke on the spot.. tried JSON.stringify instead, he wasn't having it.. Anybody hat a similar problem? Tks, regards PS: just seeing now that in the controller the createUser() is called from where the user is returned through the omit function already... so in the controller I only return and send the user
@ugurdev
Жыл бұрын
I had the same issue, not sure if it is refactored somewhere in the 1st video, but repo shows "return res.send(user);" in the controller as well
Cool ❤❤❤❤❤❤
if anyone uses NPM run this command " *npm run test -- --watch* "
My comments are automatically being deleted....I have no idea why
@TomDoesTech
2 жыл бұрын
That's weird. Sometimes YT does weird stuff with comments.
@NathanielBabalola
2 жыл бұрын
@@TomDoesTech apparently it just deleted my response to this
@TomDoesTech
2 жыл бұрын
@@NathanielBabalola We should show KZread how to build a website that works!
@NathanielBabalola
2 жыл бұрын
@@TomDoesTech hahaha, we actually should.
Hello) I am writing the fourth comment)
@lolbozland
2 жыл бұрын
I don't see record about mongodb-memory-server in file 'package'. How I have to install it, globally or another way?
why you dont use testing database? you are not testing much this way
@TomDoesTech
2 жыл бұрын
Testing against a database is a nightmare to manage in CI pipelines. If you think it's not testing enough, then test against a database. I'm usually pretty happy with the test coverage doing it this way.
I keep getting a 403 on this test describe("given the user is logged in ", () => { it("should return a 200 and create product", async () => { const jwt = signJwt(userPayload); const { statusCode, body } = await supertest(app) .post("/api/products") .set("Authorization", `Bearer ${jwt}`) .send(productPayload); expect(statusCode).toBe(200); expect(body).toEqual({}); }); }); everything works 100% on postman