Testing Express REST API With Jest & Supertest

แชร์
ฝัง
  • เผยแพร่เมื่อ 11 ต.ค. 2021
  • Repository: github.com/TomDoesTech/Testin...
    ❤️Host your applications and get 💰$100 credit (referral): m.do.co/c/1b74cb8c56f4
    📚 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.buymeacoffee.com/tomn

ความคิดเห็น • 109

  • @mikda360
    @mikda360 ปีที่แล้ว +26

    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

  • @jritzeku
    @jritzeku 2 ปีที่แล้ว +5

    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.

  • @narissatsuboi9254
    @narissatsuboi9254 ปีที่แล้ว +1

    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!

  • @user-ey2ei4oz3m
    @user-ey2ei4oz3m 2 ปีที่แล้ว +2

    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
      @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.

  • @mohamedyoussef8835
    @mohamedyoussef8835 2 ปีที่แล้ว +2

    Best tutorial on TH-cam so far... and I've been searching for months

  • @chrisjames278
    @chrisjames278 2 ปีที่แล้ว

    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
      @TomDoesTech  2 ปีที่แล้ว +1

      Thanks Chris! Glad you're enjoying the videos. Feel free to jump on the Discord server if you have any questions.

  • @ayushpaharia5452
    @ayushpaharia5452 2 ปีที่แล้ว +1

    Thanks for your efforts Tom. Love the video

  • @Ximaz-
    @Ximaz- 25 วันที่ผ่านมา +1

    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.

  • @dumbledoornguyen5966
    @dumbledoornguyen5966 ปีที่แล้ว +1

    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!

  • @salmanrana9478
    @salmanrana9478 ปีที่แล้ว +1

    Thanks for the awesom video. You made my TDD weekend fun.

  • @tyengineer0
    @tyengineer0 2 ปีที่แล้ว +8

    I am so genuinely excited for this you sir are a beacon of light in the coding world lol starting it now👌🏽💯

    • @TomDoesTech
      @TomDoesTech  2 ปีที่แล้ว +1

      That's really kind of you, even if it is a little odd :)

  • @wralith
    @wralith 2 ปีที่แล้ว +1

    This series is the best tutorial I've been following, thank you very much it is gold

    • @TomDoesTech
      @TomDoesTech  2 ปีที่แล้ว

      Thank you so much! That's really kind of you.

  • @Life2Short2BeNatty
    @Life2Short2BeNatty 2 ปีที่แล้ว

    Amazing tutorials as always, love your Typescript/Mongoose/Express series

    • @mystik5551
      @mystik5551 2 ปีที่แล้ว

      now a curious to see

  • @Scetils
    @Scetils 2 ปีที่แล้ว

    This is awesome that your are expanding the same API. I hope this series keeps going!

    • @TomDoesTech
      @TomDoesTech  2 ปีที่แล้ว +3

      Yeah, going to build a UI next to show how to use the access & refresh tokens.

  • @pscoriae6981
    @pscoriae6981 ปีที่แล้ว +1

    I was absolutely clueless on how to mock my own functions. thank you so much

  • @estifanosneway5604
    @estifanosneway5604 ปีที่แล้ว +1

    really helpful and fun, thank you.

  • @jxlim4613
    @jxlim4613 หลายเดือนก่อน +1

    This is the best tutorial ever, thank you Tom!

  • @gustavoandr7610
    @gustavoandr7610 ปีที่แล้ว

    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.

  • @Jalak-go9vm
    @Jalak-go9vm หลายเดือนก่อน +1

    Thank you so much man, learning alot from you.

  • @huyennguyenmaingoc468
    @huyennguyenmaingoc468 4 หลายเดือนก่อน +3

    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 :>

  • @nemanjazivaljevic1656
    @nemanjazivaljevic1656 2 ปีที่แล้ว +1

    Great video one of the best!

  • @user-he5uv6ij7e
    @user-he5uv6ij7e 3 หลายเดือนก่อน

    Excellent ! Thank you so much

  • @purvimodi__
    @purvimodi__ 2 ปีที่แล้ว +1

    Thanks you so much this video helped me a lot in braking the code and testing .

  • @030426101993
    @030426101993 2 ปีที่แล้ว

    awesome video on testing with Jest

  • @good-dev-student
    @good-dev-student ปีที่แล้ว +1

    Good video! I watched it for the second time.

  • @mahendranath2504
    @mahendranath2504 2 ปีที่แล้ว

    Thanks you so much 👍🏼🎉🙏

  • @zackOverflow
    @zackOverflow 2 ปีที่แล้ว

    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.

  • @mohammedsardar3779
    @mohammedsardar3779 9 หลายเดือนก่อน

    Thank you. Any video for complex json object test cases scripts example in jest?

  • @attilaszombathelyi3
    @attilaszombathelyi3 4 หลายเดือนก่อน

    great job.... thx

  • @beloaded3736
    @beloaded3736 2 ปีที่แล้ว +1

    Thanks sir 😊

  • @MeetKoriya-cu7bm
    @MeetKoriya-cu7bm ปีที่แล้ว

    can you please tell me which vs code extension you are using for highlighting the code block

  • @MajidMajid-bh8nm
    @MajidMajid-bh8nm ปีที่แล้ว

    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?

  • @chrisl8162
    @chrisl8162 ปีที่แล้ว +1

    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.

  • @321123580
    @321123580 ปีที่แล้ว

    When testing api with ject, do you actually need to have data in database?

  • @mohamedyoussef8835
    @mohamedyoussef8835 2 ปีที่แล้ว +1

    Awesome Tutorial +++++++++++++++ Thank you.

  • @1dforever952
    @1dforever952 2 ปีที่แล้ว

    which terminal you are using in VSCode?

  • @arberi99
    @arberi99 2 ปีที่แล้ว

    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
      @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
      @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
      @TomDoesTech  2 ปีที่แล้ว +1

      @@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: th-cam.com/video/BWUi6BS9T5Y/w-d-xo.html

  • @HarshPatel-ku9db
    @HarshPatel-ku9db ปีที่แล้ว

    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.

  • @Bahmanasheghii
    @Bahmanasheghii ปีที่แล้ว +1

    awesome tutorial🤌

  • @kylegeib9161
    @kylegeib9161 2 ปีที่แล้ว +2

    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.

  • @ayoubtahir2116
    @ayoubtahir2116 ปีที่แล้ว +1

    .set('Authorization', `Bearer ${jwt}`) not working any idea why?

  • @kimshares1487
    @kimshares1487 2 ปีที่แล้ว +1

    is it possible for someone to replace where we used mongodb-memory-server with the real MongoDB server?

  • @ahoymatey1234
    @ahoymatey1234 2 ปีที่แล้ว

    great tutorial keep it up but why did you need ts-ignore on the mockReturnValue?

    • @demamdq2346
      @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.

  • @S_c_0_0_p
    @S_c_0_0_p ปีที่แล้ว

    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
      @TomDoesTech  ปีที่แล้ว

      It's an autocomplete plugin for zsh

  • @Etheriiss
    @Etheriiss ปีที่แล้ว

    Even if I mock the service for user it still calls mongodb and creates it in database. Any thoughts?

  • @aryanrahman3212
    @aryanrahman3212 ปีที่แล้ว

    You're awesome!

  • @osemudiamhen
    @osemudiamhen 2 ปีที่แล้ว

    Hi! Great tutorial! Just wanted to ask what file icon theme are you using on vscode? thank you!

    • @TomDoesTech
      @TomDoesTech  2 ปีที่แล้ว

      I think it's just the default theme

    • @osemudiamhen
      @osemudiamhen 2 ปีที่แล้ว

      @@TomDoesTech okay thank you!

  • @Stefq00
    @Stefq00 5 หลายเดือนก่อน

    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.

  • @neddygonzalez4827
    @neddygonzalez4827 4 หลายเดือนก่อน

    Didn't watch the whole video, but was wondering if you do unit tests in the video?

  • @seroyjosielmarkm.2736
    @seroyjosielmarkm.2736 2 หลายเดือนก่อน

    When deploying the website should I also upload the test?

  • @LuisAlbertoSandovalArevalo
    @LuisAlbertoSandovalArevalo 2 ปีที่แล้ว +1

    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
      @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
      @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

  • @arcan762
    @arcan762 2 ปีที่แล้ว +1

    tldr version??

  • @neghidev
    @neghidev ปีที่แล้ว

    Hi, great video. I have a question tho, how do I mock a class service?

    • @TomDoesTech
      @TomDoesTech  ปีที่แล้ว +1

      Just mock it like it's a function, because that's what it is

    • @neghidev
      @neghidev ปีที่แล้ว

      @@TomDoesTech Ok, thank you very much

  • @ParthKamal-iy9bf
    @ParthKamal-iy9bf 9 หลายเดือนก่อน

    is jest used in this video . what is the difference between jest and supertest ?

    • @TomDoesTech
      @TomDoesTech  9 หลายเดือนก่อน

      Yes, supertest is for sending HTTP requests in your tests

  • @mohamedyoussef8835
    @mohamedyoussef8835 2 ปีที่แล้ว

    Please show us how to make the React front end to this API

    • @TomDoesTech
      @TomDoesTech  2 ปีที่แล้ว

      Hey Mohamed, thank you for your kind comments. The video you're after is here: th-cam.com/video/oSz23pPBpFY/w-d-xo.html
      Then you may want to add Google OAuth: th-cam.com/video/Qt3KJZ2kQk0/w-d-xo.html

  • @jiaxushen9881
    @jiaxushen9881 2 ปีที่แล้ว

    @41:10 line 6, const app = createApp(), createApp() is not defined.

    • @TomDoesTech
      @TomDoesTech  2 ปีที่แล้ว

      Di you watch the part where I refactored the app?

  • @good-dev-student
    @good-dev-student ปีที่แล้ว +1

    Cool ❤❤❤❤❤❤

  • @mucki2109
    @mucki2109 2 ปีที่แล้ว

    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
      @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

  • @shegunadebimpe-ojo9485
    @shegunadebimpe-ojo9485 ปีที่แล้ว

    do you have a video with javascript and not typescript?

  • @yashwanthbm7543
    @yashwanthbm7543 หลายเดือนก่อน

    do we learn UNIT testing here?

  • @tylerwong3290
    @tylerwong3290 2 ปีที่แล้ว

    I keep getting "TypeError: (0 , supertest_1.default) is not a function." What's the problem here?

    • @TomDoesTech
      @TomDoesTech  2 ปีที่แล้ว

      Try importing supertest like `import * as supertest from 'supertest'`

    • @tylerwong3290
      @tylerwong3290 2 ปีที่แล้ว

      ​@@TomDoesTech It worked thank you!

  • @markokraljevic1590
    @markokraljevic1590 2 ปีที่แล้ว

    you didnt explain clearly what is the difference between clearMocks and resetMocks? and what is the difference between supertest and plain axios?

    • @TomDoesTech
      @TomDoesTech  2 ปีที่แล้ว +1

      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.

  • @michaelumeokoli
    @michaelumeokoli ปีที่แล้ว

    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.

  • @StringSwoosh
    @StringSwoosh 2 ปีที่แล้ว

    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
      @StringSwoosh 2 ปีที่แล้ว

      Nice video btw! Wrote my first nodejs (ts) tests!

    • @TomDoesTech
      @TomDoesTech  2 ปีที่แล้ว +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
      @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
      @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#) >_

  • @And1997Ruz
    @And1997Ruz 11 หลายเดือนก่อน

    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

  • @saurabhgupta6691
    @saurabhgupta6691 ปีที่แล้ว

    ● 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
      @ricardorien ปีที่แล้ว

      anoying issue

    • @ricardorien
      @ricardorien ปีที่แล้ว

      Bro, no you have to instal ts-jest as a dependency: for example:
      yarn add ts-jest -D

  • @codingtraining0102
    @codingtraining0102 2 ปีที่แล้ว

    if anyone uses NPM run this command " *npm run test -- --watch* "

  • @lolbozland
    @lolbozland 2 ปีที่แล้ว

    Hello) I am writing the fourth comment)

    • @lolbozland
      @lolbozland 2 ปีที่แล้ว +1

      I don't see record about mongodb-memory-server in file 'package'. How I have to install it, globally or another way?

  • @NathanielBabalola
    @NathanielBabalola 2 ปีที่แล้ว +1

    My comments are automatically being deleted....I have no idea why

    • @TomDoesTech
      @TomDoesTech  2 ปีที่แล้ว

      That's weird. Sometimes YT does weird stuff with comments.

    • @NathanielBabalola
      @NathanielBabalola 2 ปีที่แล้ว

      @@TomDoesTech apparently it just deleted my response to this

    • @TomDoesTech
      @TomDoesTech  2 ปีที่แล้ว +1

      @@NathanielBabalola We should show TH-cam how to build a website that works!

    • @NathanielBabalola
      @NathanielBabalola 2 ปีที่แล้ว

      @@TomDoesTech hahaha, we actually should.

  • @markokraljevic1590
    @markokraljevic1590 2 ปีที่แล้ว

    why you dont use testing database? you are not testing much this way

    • @TomDoesTech
      @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.

  • @michaelumeokoli
    @michaelumeokoli ปีที่แล้ว

    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