Your Nest videos are easily the best I've seen. Could you do another one on testing where you set up a Development database using migrations, and then only do E2E testing with the database as a part of the testing.
thanks! you’re thinking like a true full e2e where it actually writes to a db instead of mocking it out? Sure I can potentially make something for that
@@mariusespejo I would absolutely love that. I spent my day setting up a docker and figuring out how to use a node environment to choose which one to spin up upon test. But I've been having a hell of a time with jest dependencies being all messed up for some reason. I appreciate you!
Great introduction. I've been banging my head trying to get mocking to work while using typeDI and typeORM. Might just switch my whole backend to use NestJS after watching this =)
great! I haven’t tried typeDI but if you’re definitely looking for a DI-based framework you can’t go wrong with nest, and it’s got great integration with typeorm so you’re also covered there
I really miss git repository here :( Sometimes when you want to jump from file to file its really difficult to switch between different timestamps in video.
@@mariusespejo A Project! I would be happy if you can build a project connecting all the topics that you have covered so far. Would be really awesome to see how these things work together. Thanks
Yup I actually agree, overtime I’ve found it better to actually just run tests off of a real database to get e2e as close to real as possible, but it does require a little extra setup. thanks for stopping by to comment!
Great content you've provided here sir! Just wanna leave a quick note that if you've created a custom class for your Repository you'll have to write "provide: UserRepository," instead of "provide: getRepositoryToken(User)," Keep up the good work!
27:10 One comment about the 'expect().toBeCalled()' assertions making the tests brittle. They already *are* brittle, because you are implicitly relying on the underlying implementation in your choice of which methods to define in your mockUserRepostory. For example, if you switched to using insert() and query() in the service, your mockUserRepository probably wouldn't have those methods defined, so the test would fail anyway. For a real life project, I am needing to effectively mock a lot of prisma in this manner. I'd also potentially like to be able to inject different provider overrides for different tests: any ideas how? Great tutorial though, thanks.
Fair enough good point! I feel like mocking ORM/query builders in general always leads to that. I think the only way to get around that is by having an extra layer of abstraction so that you’re not dealing with the underlying implementation directly. E.g. for typeorm for example you can do custom repositories: orkhan.gitbook.io/typeorm/docs/custom-repository I imagine that would result in just needing to mock a single method from the repo. As for your override question, you can maybe use multiple describe blocks with their own test beds for each set of tests with different overrides. Not sure there’s a better way than that
@@mariusespejo Thanks. And, of course, this is true of any dependency mocking. You try and mock the smallest part of the dependency's interface, but that means understanding the implementation details of the code under test. Eventually, you need a test suite to check that the mock implementation works correctly.
Hey, I am looking for a setup for test suites in NestJS, but with addition of factories for classes, in order to help me with seeding and "Arrange" Step of the Test. Any idea where to watch that? Especially, for complex schemas where i.e. I want to test a module, which every entity depends on the creation of others.
Thanks man ... really nice groundwork for us to build on top. I'm enjoying myself doing some old school TDD (is this still a thing?) on an idea I'm having and one thing I'm trying to achieve is that in the name of the technique, iow the unit tests should drive how I design my units and the integration tests how I design my integrations. At the 27min mark, there is a comment on changes impacting the test code ... but wouldn't that be exactly the reason why you are writing them? I mean, you want to have an asset that tells you if any of the changes performed in your existing code base is breaking it, also, if the tests should be driving the design, then I would think it's a good idea to write them first and let them fail, then your redesign now has a very concrete objective, to pass the tests. This has limitations but seems pretty fun to do and makes writing tests much less cumbersome (and with a slight lesser feeling of worthlessness?) and one I can tell right away is that it should not dictate how the unit being tested will work, but instead rely on testing its Inputs and Outputs (Black Box Testing).
Yeah some good points. Yes in general your tests should act as a safety net to capture any moment that you MIGHT have broken previous functionality. That is precisely the purpose of tests. However IDEALY your tests should not simply be a mirror of your exact implementation details. If I have a test that asserts something is created, it shouldn’t matter exactly HOW it was created. Otherwise you’re really just testing implementation details and that leads to brittle tests. That’s the point I was trying to make around the 26:50-27min mark, that in ideal terms I should be able to change the underlying query but as long as it still results in the same expected result, then my test should pass. That’s basically what you pointed out with black box testing so I’m not sure where the disconnect is, it sounds like we agree on the same core principle. However I was calling it out specifically because at that example unit test, if you mock the dependency, it’s a bit hard to create a mock that doesn’t ultimately behave or mirror your implementation details. Also this video was really more a lesson on how to setup tests for Nest specifically and not necessarily on TDD. However I actually do think TDD is a great practice, in general anything that promotes designing the API first in some way is a good thing
@@mariusespejo thanks for the answer man, no disagreement indeed, I just fell the need to get that point you made and bring the TDD talk. Thanks again for the video man, much success!
Hi Marius, following your video (e2e testing), I keep getting this error: Nest can't resolve dependencies of the JwtStrategy (AuthService, ?). Please make sure that the argument ConfigService at index [1] is available in the AuthModule context. I tried the overrideProvider for ConfigService, but no hope. Any ideas? Thank you
That means you didn’t register the config module in your auth module. Alternatively you can register it globally docs.nestjs.com/techniques/configuration#use-module-globally
@@mariusespejo It is registered globally in the appModule. I added it into the authModule and now I get: Nest can't resolve dependencies of the UserModel (?). Please make sure that the argument DatabaseConnection at index [0] is available in the MongooseModule context.
I mean it’s telling you exactly what the problem is, the module you’re trying to use is missing dependencies. In a test not all of your modules are necessarily registered like in the real app, so it’s not able to find things. That means in your test you either need to add those missing dependencies in the test module, or you need to mock them
Hi Marius! Question, should we always create a unit test for our service? Or should we just create an integrarion test? I want my test no to be related to the implementation only on the output of the service. What do uou think?
Having a mix of both is good but whether or not you should always do unit tests is up to you. If you had to pick one to focus on, definitely the integration tests are more valuable.
I'm sure I'm missing the point of it, but it seems to me the tests are testing the mocked implementation of the class methods, rather than the actual class methods itself? How do I run the actual logic that I've written in the classes instead of the mocked simplified implementations? Or am I misunderstanding the point of running tests?
It’s a valid argument, but you have to understand you’re not testing how the dependencies work. You’re testing just the unit you’re on, in isolation. These are tests that are meant to run quickly. In very simple examples like I have here it does seem low value. I definitely recommend writing more integration or e2e tests where you do test things “for real” together, with the trade off being slower to run and often higher complexity. Or you can mix strategies where you mock some and not others. It’s up to you.
Hey! thanks for the video!. Im trying to create test filed on an existing project, npx nest generate test place, place being the name of the module i want to test. I get "Invalid schematic "test". Please, ensure that "test" exists in this collection.". :/ Do i need to install it separately?
I would test them as usual and have those things run for real. However it depends on the underlying implementation behind those decorators. For example if you have an auth guard that integrates with an external identity provider, then I would either mock that guard or use a different passport strategy specifically for testing. RBAC guards I would definitely try to test for real, but that’s where your auth mock will come into play (e.g simulating different users with different roles). If you do need to mock any of it, there’s a small detail in the video where I briefly show that you can also do things like overrideGuard, overrideInterceptor, etc.
Create() doesn’t create the ID, the save does (which is where inserting would actually happen). And you should notice that the save mock does have ID creation in it. That’s why the test passes
Thanks what are your thoughts on testing the typeorm entities? How do we test db constraints in entity or add validation at entity level using class validator?
You’re meant to utilize class validator on the dto not the entity, because you’re validating the data that’s coming in from a client not data coming out of the db which is what the entity classes represent. You can involve a real in-memory db if you wanted to but I don’t really see a ton of value in testing db constraints, it’s not your job to verify that the database is working as it’s supposed to. However that’s not to say that testing the integration with a real db is useless, there is value in doing a true end-to-end integration test. But the point is to test the integration not the individual database constraints
Lets say for example your service layer throws “EntityNotFound” which the controller catches so it can then throw NotFoundException. Then in your controller unit test the service mock for one of your tests bust be setup to throw EntityNotFound, then you can assert NotFoundException was thrown. Similar idea for the service. If you were doing an e2e test then similar idea but instead you’d actually assert that you got a 404 status response. Hope that helps
Great video! Any idea on how to mock a request session using supertest? My controller pulls data off of the request session. I'd like to be able to mock that in my e2e test
In theory you just need a mock middleware which puts data inside req.session, and that data could be whatever you want. Or otherwise maybe you could mock other parts of the pipeline, e.g. if you had a guard that checks data in session, you could mock that guard instead
Excellent video, love the way you explain things. So simplified, easy to go through and grasp knowledge. Have you consider doing Udemy courses? Cause I strongly believe people would like to aquire more depful content from you.
In unit test, I saw that mostly we mock everything just to get the expected result, but if we mock something it for sure to be an expected result right ? I am curious let say in my service method contains some logic, how will this code be tested ? or is that we dont really need to test it ? most of unit testing video/ tutorial only showthe case where the service method that is simple, like have single line of code and mock dependency method that being called. What if I have a service method as below logic(input): { // do something with input example data transformation return input.toUpperCase(); } when we write expect(service.logic(input)).toEqual(expectedResult); is that method really executed ? meaning it really call the exact service.logic method and return an upper case of the input ?
We mock the dependencies but not the actual underlying logic of the thing your testing. In your example you’d unit the service by making sure that the output is transformed, your example would require zero mocking. But let’s say it uses a repository to select the input from the database, then your service logic uppercases it prior to returning, then your mock repository should return some mock return value and you would assert that you not only got the mock value but also that it’s all uppercase
Great video man, but I have a problem, I have a folder with multiples resources into, this called, phase-two, when I try to run any test file, doesn't work, show me a message about the Service Name can't be found it and other stuff. On the other hand, the first phase, called phase-one, doesn't have any issue, but in this folder the module is a same level of the test file generate by Nest. Do you know any solution for that?
Generally in tests if it says it can’t find a dependency it’s because you test module didn’t include it (or a mock of it) so it doesn’t know what to inject, hence it will say can’t be found
Could you suggest a clean way of how test db should be configured for tests. Sould entire database module be mocked, or just configuration file changed, or environment. How migration and seeds should be implemented. Maybe you know great article about all of this?
It depends entirely on how “real” you want it to be. You could literally spin up a database like mysql/postgres with docker for example and set it up in such a way that it starts fresh per test. Run migrations, seed data, trigger your queries and make your assertions, wipe the db, rinse repeat. But the tradeoff is complexity and tests running slower. It’s also more complex doing that on CI, depending on your setup. Next best thing, maybe the same thing but run sqlite in memory. Tradeoff is that if you’re not actually using sqlite in production then there are API and behavior differences compared to your real DB. Next option is mocking the database layer entirely, perhaps at the ORM level. It’s easier, you don’t have to deal with migrations, tests are quick. But the tradeoff is your tests are the farthest away from being “real”. So it all boils down to how much confidence do you want your tests to produce and how complex of a setup are you willing to put up with
Hey man, in the first test example, how can I test if my validation with class-validator are working? example: test if my response have a status code of 400 if no nome is provided, if the message contain "no name provided"? I'm trying this, but I don't know how :(
@Marius you can simply configure jest to use the same import strategy as vs code with the following config ``` "jest": { "moduleFileExtensions": [ "js", "json", "ts" ], "rootDir": "./", "modulePaths": [ "" ], "testRegex": "spec.ts$", "transform": { "^.+\\.(t|j)s$": "ts-jest" }, "collectCoverageFrom": [ "**/*.(t|j)s" ], "coverageDirectory": "../coverage", "testEnvironment": "node" } ```
@@mariusespejo Btw, have you found a way to use a vscode plugin to run the test? I would love to have a better interface for reviewing the test and see what values was returned and so on.
There is a jest vs code extension that I tried before that can do something like that but I wasn’t a fan of it. If you google vs code jest it’ll be the first result
@@mariusespejo I also tried that one out, but it is pretty slow compared to just using the cli tool, I was hoping I had missed some gold right in front of my eyes :)
Great video buddy. I wrote my first unit test for one endpoint in a pretty fleshed out backend API, and it was over 136 lines long. Is that normal? I imagine that if i do the rest of the endpoints in the controller file it will reach to 500 lines-ish
A controller unit test generally should be short. Most of your business logic should be in services/providers meaning a controller should be pretty slim and unit tests of it in most cases just need to assert that it’s calling the right service methods (which can be mocked). The endpoint e2e tests I would expect to be quite a bit longer because you’re integrating all the things including authentication, authorization, validation, middlewares, then finally asserting expected status codes and body response, etc. The e2e test is where you’ll get the most value, specially if you keep mocks to a minimum
@@mariusespejo thanks for the thoughtful response. I'll revisit the code and maybe try to get rid of sections. It makes sense as the controller only handles requests/responses.
Great tutorial, really helped me with mocking my repository on the test file. I have really been struggling with it. I have a question though. How do I override a guard in my controller and also override a provider at the same time. I tried .overrideProvider().overrideGuards() but it didn't work and I kept getting the error "Property 'overrideProvider' does not exist on type 'OverrideBy'.". I would really appreciate your guidance on how to go about it. Thank you
You missing a few things there, you need to do something like this: .overrideProvider(MyService).useValue(myServiceMock).overrideGuard(MyGaurd).useValue(myGuardMock) Basically you need to tell it HOW to do the override. I think there is also .useClass() as an alternative to useValue() if your mock is a class and not an instance/object
That was really helpful for me. I discovered so many things about testing and now feel like I'm ready to write these tests. I have a question: what code editor theme have you been using during this video? ;) Isn't the Night owl?
@@mariusespejo I've already seen a really good tutorial. Would be cool if you went even more deeply into the subject of authentification and authorization. like RBAC and CASL
technically speaking e2e IS an integration test, it just happens to to cover the entire flow end to end like from a user’s perspective them making a request and getting a response back
PASS src/modules/users/controllers/users.controll.spec.ts ● Console console.log debug: Logging initialized at debug level {"timestamp":"10-02-2023 13:00:10"} at Console.log (node_modules/winston/lib/winston/transports/console.js:79:23) at async Promise.all (index 4) at async Promise.all (index 9) my app when I running test. its pass the test but it not log the test text. can you help me.
Holy cow! its too good lecture. And I have a question. I am trying to do integration test. And my modules use axios. And then I got error which indicates that jest cannot parse axios. Can you give some suggestions on this ?
Nest has an HTTP module @nestjs/axios which basically lightly wraps axios and you make requests via HttpService, meaning it’s something injected and can be easily mocked in tests. Anything that you use directly will be slightly harder to mock unless you want to mock it at the jest level (which can also do its own module mocking) vs at the nest level
yes should be mostly the same concepts for graphql endpoints but the key difference is for your e2e tests they will always be a POST with a request body containing the query
yeah I don’t see why not. You might want to use something that’s in memory though like sqlite or something and you’ll need to make sure the database is wiped for each test. You likely will also need to migrate and/or seed per test.
That said, E2E tests aren't usually meant to use a mock repository, but a fully provisioned test version of it that's as close to the production setup as possible. I started working with NestJs very recently and love how it keeps the code organized, but it's not very helpful in creating integration tests, only unit (total isolation) and E2E (close to production). I supposed E2E tests do technically count as integration tests though, so it's not a huge deal either.
Yeah I would consider e2e as integration. Also you can run e2e tests with an actual db if you really wanted to, e.g. a sqlite for example, but you’d have to migrate/seed and wipe the db before/after each test. That added overhead/complexity may or may not be worth it depending on your use case or preference
You might be mocking the dependencies but you’re still testing that the logic in your functions are producing the intended results. The examples here might be too simple to fully see the value of it, I was mostly showing the HOW but I recommend reading about the WHY
Well the point of unit tests is to isolate and typically provide mock dependencies. Is it able to function in isolation? I’m just explaining how to do it. Whether or not that’s useful to you is up to you. But it’s the entire point of dependency injection, to be able to easily inject alternative dependencies (e.g. mocks in this case) I do think the e2e tests are where most of the value is, specially if you minimize mocks and setup a real db so that you don’t have to mock the queries. But you need a little bit more setup for that, e.g. you need to be able to reset your database for each test. How much you actually mock is ultimately up to you, e.g. how much of a unit vs integration test do you want to do.
Your Nest videos are easily the best I've seen. Could you do another one on testing where you set up a Development database using migrations, and then only do E2E testing with the database as a part of the testing.
thanks! you’re thinking like a true full e2e where it actually writes to a db instead of mocking it out? Sure I can potentially make something for that
@@mariusespejo I would absolutely love that. I spent my day setting up a docker and figuring out how to use a node environment to choose which one to spin up upon test. But I've been having a hell of a time with jest dependencies being all messed up for some reason.
I appreciate you!
thanks for awesome tutorial video, watching your video with speed 1.5 is always my way for running through all of it then begin to coding :)))
Glad to know you can still understand me at 1.5x haha thanks!
Brother, you are a life savior. I look for many resources but couldn't find that overriding thing. Thanks so much, brother 😁👍👍 Subs to your channel
Awesome glad to help, thanks!
More great content. The music is cool and soothing to start, and glad you dropped it as the 'real' content started. :)
Thanks! I mostly don’t add music in newer stuff, there’s a thin line between it being entertaining and potentially distracting
Dude, you rock! Congratulations for your amazing work :)
Great introduction. I've been banging my head trying to get mocking to work while using typeDI and typeORM. Might just switch my whole backend to use NestJS after watching this =)
great! I haven’t tried typeDI but if you’re definitely looking for a DI-based framework you can’t go wrong with nest, and it’s got great integration with typeorm so you’re also covered there
Crystal clear as usual, Great video Marius!
great work, very well explained. greetings from Argentina 🔵⚪🔵
Great tutorial. Your efforts is truly appreciated
Thank you!
I really miss git repository here :( Sometimes when you want to jump from file to file its really difficult to switch between different timestamps in video.
thanks for you input, I do need to work on providing source code along with the content
@@mariusespejo that would be greatly appreciated :)
so clear, Thank you so much would like to see more of these.
thanks Tushar! definitely more of these in the future. Anything specific you were hoping to be covered?
@@mariusespejo A Project! I would be happy if you can build a project connecting all the topics that you have covered so far. Would be really awesome to see how these things work together. Thanks
thank you so much, you've put everything on the shelves.
You're welcome!
@Marius Espejo, how to override multiple services in createTestingModule? My controller A is dependent on service B,C,D
Thanks a lot tried clicking the subscribe button to subscribe twice...
Thank you, the unit test part was perfect, the e2e I would prefer not mocking anything, but thanks anyway for the good content
Yup I actually agree, overtime I’ve found it better to actually just run tests off of a real database to get e2e as close to real as possible, but it does require a little extra setup. thanks for stopping by to comment!
Great content you've provided here sir!
Just wanna leave a quick note that if you've created a custom class for your Repository you'll have to write "provide: UserRepository," instead of "provide: getRepositoryToken(User),"
Keep up the good work!
thanks Anderson! good note, I haven’t actually tried making a custom class for repositories yet, will take a look at that
@27:40 integration tests begins
Really helpful tutorial, clear and straight forward. Thanks much!
27:10 One comment about the 'expect().toBeCalled()' assertions making the tests brittle.
They already *are* brittle, because you are implicitly relying on the underlying implementation in your choice of which methods to define in your mockUserRepostory.
For example, if you switched to using insert() and query() in the service, your mockUserRepository probably wouldn't have those methods defined, so the test would fail anyway.
For a real life project, I am needing to effectively mock a lot of prisma in this manner. I'd also potentially like to be able to inject different provider overrides for different tests: any ideas how?
Great tutorial though, thanks.
Fair enough good point! I feel like mocking ORM/query builders in general always leads to that. I think the only way to get around that is by having an extra layer of abstraction so that you’re not dealing with the underlying implementation directly. E.g. for typeorm for example you can do custom repositories: orkhan.gitbook.io/typeorm/docs/custom-repository
I imagine that would result in just needing to mock a single method from the repo.
As for your override question, you can maybe use multiple describe blocks with their own test beds for each set of tests with different overrides. Not sure there’s a better way than that
@@mariusespejo Thanks.
And, of course, this is true of any dependency mocking. You try and mock the smallest part of the dependency's interface, but that means understanding the implementation details of the code under test.
Eventually, you need a test suite to check that the mock implementation works correctly.
You saved my day, thank you.
Hey, I am looking for a setup for test suites in NestJS, but with addition of factories for classes, in order to help me with seeding and "Arrange" Step of the Test. Any idea where to watch that?
Especially, for complex schemas where i.e. I want to test a module, which every entity depends on the creation of others.
AWESOME VIDEO, THANK YOU SO MUCH!
subscribed also
thanks! 🙌
Thanks man ... really nice groundwork for us to build on top. I'm enjoying myself doing some old school TDD (is this still a thing?) on an idea I'm having and one thing I'm trying to achieve is that in the name of the technique, iow the unit tests should drive how I design my units and the integration tests how I design my integrations. At the 27min mark, there is a comment on changes impacting the test code ... but wouldn't that be exactly the reason why you are writing them? I mean, you want to have an asset that tells you if any of the changes performed in your existing code base is breaking it, also, if the tests should be driving the design, then I would think it's a good idea to write them first and let them fail, then your redesign now has a very concrete objective, to pass the tests. This has limitations but seems pretty fun to do and makes writing tests much less cumbersome (and with a slight lesser feeling of worthlessness?) and one I can tell right away is that it should not dictate how the unit being tested will work, but instead rely on testing its Inputs and Outputs (Black Box Testing).
Yeah some good points. Yes in general your tests should act as a safety net to capture any moment that you MIGHT have broken previous functionality. That is precisely the purpose of tests. However IDEALY your tests should not simply be a mirror of your exact implementation details. If I have a test that asserts something is created, it shouldn’t matter exactly HOW it was created. Otherwise you’re really just testing implementation details and that leads to brittle tests. That’s the point I was trying to make around the 26:50-27min mark, that in ideal terms I should be able to change the underlying query but as long as it still results in the same expected result, then my test should pass. That’s basically what you pointed out with black box testing so I’m not sure where the disconnect is, it sounds like we agree on the same core principle. However I was calling it out specifically because at that example unit test, if you mock the dependency, it’s a bit hard to create a mock that doesn’t ultimately behave or mirror your implementation details.
Also this video was really more a lesson on how to setup tests for Nest specifically and not necessarily on TDD. However I actually do think TDD is a great practice, in general anything that promotes designing the API first in some way is a good thing
@@mariusespejo thanks for the answer man, no disagreement indeed, I just fell the need to get that point you made and bring the TDD talk. Thanks again for the video man, much success!
Thank you! This helped me a lot!
Glad it helped!
Thank you very much, it helped a lot!
any chance of the starter code so people can follow quickly without much set up
Excellent tutorial. where were you 1 year ago? I had to learn testing the hard way.
A year ago? likely being a bum and not making videos haha glad it helped you!
Lovely video. Thanks A Lot
thanks! 🙏 glad you like it
Yes for the end to end test so that your E2E tests act as a living documentation . Thanks
Hello Marius, Great tutorial.
Hello! Glad you liked it!
Hi Marius, following your video (e2e testing), I keep getting this error: Nest can't resolve dependencies of the JwtStrategy (AuthService, ?). Please make sure that the argument ConfigService at index [1] is available in the AuthModule context.
I tried the overrideProvider for ConfigService, but no hope. Any ideas? Thank you
That means you didn’t register the config module in your auth module. Alternatively you can register it globally docs.nestjs.com/techniques/configuration#use-module-globally
@@mariusespejo It is registered globally in the appModule. I added it into the authModule and now I get: Nest can't resolve dependencies of the UserModel (?). Please make sure that the argument DatabaseConnection at index [0] is available in the MongooseModule context.
I mean it’s telling you exactly what the problem is, the module you’re trying to use is missing dependencies. In a test not all of your modules are necessarily registered like in the real app, so it’s not able to find things. That means in your test you either need to add those missing dependencies in the test module, or you need to mock them
@@mariusespejo Hi again, I resolved it by mocking configService. Thanks man :)
Glad you got it figured out!
Hi Marius! Question, should we always create a unit test for our service? Or should we just create an integrarion test? I want my test no to be related to the implementation only on the output of the service. What do uou think?
Having a mix of both is good but whether or not you should always do unit tests is up to you. If you had to pick one to focus on, definitely the integration tests are more valuable.
Amazing Video!
I'm sure I'm missing the point of it, but it seems to me the tests are testing the mocked implementation of the class methods, rather than the actual class methods itself? How do I run the actual logic that I've written in the classes instead of the mocked simplified implementations? Or am I misunderstanding the point of running tests?
It’s a valid argument, but you have to understand you’re not testing how the dependencies work. You’re testing just the unit you’re on, in isolation. These are tests that are meant to run quickly. In very simple examples like I have here it does seem low value. I definitely recommend writing more integration or e2e tests where you do test things “for real” together, with the trade off being slower to run and often higher complexity. Or you can mix strategies where you mock some and not others. It’s up to you.
Hey! thanks for the video!. Im trying to create test filed on an existing project, npx nest generate test place, place being the name of the module i want to test. I get "Invalid schematic "test". Please, ensure that "test" exists in this collection.". :/ Do i need to install it separately?
Invalid schematic means it’s not supported for generate, you’ll just have to make the file manually.
nice explanation. How would you approach testing endpoints that have guards / decorators and interceptors etc..
I would test them as usual and have those things run for real. However it depends on the underlying implementation behind those decorators. For example if you have an auth guard that integrates with an external identity provider, then I would either mock that guard or use a different passport strategy specifically for testing. RBAC guards I would definitely try to test for real, but that’s where your auth mock will come into play (e.g simulating different users with different roles).
If you do need to mock any of it, there’s a small detail in the video where I briefly show that you can also do things like overrideGuard, overrideInterceptor, etc.
on the service tests, your mock implementation of create() is not creating an id. i don't know why the test of it passes.
Create() doesn’t create the ID, the save does (which is where inserting would actually happen). And you should notice that the save mock does have ID creation in it. That’s why the test passes
Thanks what are your thoughts on testing the typeorm entities? How do we test db constraints in entity or add validation at entity level using class validator?
You’re meant to utilize class validator on the dto not the entity, because you’re validating the data that’s coming in from a client not data coming out of the db which is what the entity classes represent. You can involve a real in-memory db if you wanted to but I don’t really see a ton of value in testing db constraints, it’s not your job to verify that the database is working as it’s supposed to. However that’s not to say that testing the integration with a real db is useless, there is value in doing a true end-to-end integration test. But the point is to test the integration not the individual database constraints
Lovely tutorial
Great content, and if I have logic in my service layer that can return errors like 404, 409, how do I test this in the controller and service layer?
Lets say for example your service layer throws “EntityNotFound” which the controller catches so it can then throw NotFoundException. Then in your controller unit test the service mock for one of your tests bust be setup to throw EntityNotFound, then you can assert NotFoundException was thrown. Similar idea for the service. If you were doing an e2e test then similar idea but instead you’d actually assert that you got a 404 status response. Hope that helps
Great video! Any idea on how to mock a request session using supertest? My controller pulls data off of the request session. I'd like to be able to mock that in my e2e test
In theory you just need a mock middleware which puts data inside req.session, and that data could be whatever you want. Or otherwise maybe you could mock other parts of the pipeline, e.g. if you had a guard that checks data in session, you could mock that guard instead
Thank you kindly for this video.
Excellent video, love the way you explain things. So simplified, easy to go through and grasp knowledge. Have you consider doing Udemy courses? Cause I strongly believe people would like to aquire more depful content from you.
Yeah I’ve thought about making paid courses, but for now it’s all just here for free :)
the amount of uncomitted files gives me anxiety :D
on a serious note, great video :)
do you happen to have this on github by any chance?
In unit test, I saw that mostly we mock everything just to get the expected result, but if we mock something it for sure to be an expected result right ?
I am curious let say in my service method contains some logic,
how will this code be tested ? or is that we dont really need to test it ?
most of unit testing video/ tutorial only showthe case where the service method that is simple,
like have single line of code and mock dependency method that being called.
What if I have a service method as below
logic(input): {
// do something with input example data transformation
return input.toUpperCase();
}
when we write
expect(service.logic(input)).toEqual(expectedResult);
is that method really executed ? meaning it really call the exact service.logic method and return an upper case of the input ?
We mock the dependencies but not the actual underlying logic of the thing your testing. In your example you’d unit the service by making sure that the output is transformed, your example would require zero mocking. But let’s say it uses a repository to select the input from the database, then your service logic uppercases it prior to returning, then your mock repository should return some mock return value and you would assert that you not only got the mock value but also that it’s all uppercase
Great Video
How to do e2e test on getManager().query(). While doing so, it always takes default connection
Great content.
Great tutorial. and can you put repo link please to make it doc for me ?
you are the best!, thank you!
You’re welcome!
Great video man, but I have a problem, I have a folder with multiples resources into, this called, phase-two, when I try to run any test file, doesn't work, show me a message about the Service Name can't be found it and other stuff. On the other hand, the first phase, called phase-one, doesn't have any issue, but in this folder the module is a same level of the test file generate by Nest. Do you know any solution for that?
Generally in tests if it says it can’t find a dependency it’s because you test module didn’t include it (or a mock of it) so it doesn’t know what to inject, hence it will say can’t be found
@@mariusespejo Thanks, I found a video where solved that problem.
Could you suggest a clean way of how test db should be configured for tests. Sould entire database module be mocked, or just configuration file changed, or environment. How migration and seeds should be implemented. Maybe you know great article about all of this?
It depends entirely on how “real” you want it to be. You could literally spin up a database like mysql/postgres with docker for example and set it up in such a way that it starts fresh per test. Run migrations, seed data, trigger your queries and make your assertions, wipe the db, rinse repeat. But the tradeoff is complexity and tests running slower. It’s also more complex doing that on CI, depending on your setup. Next best thing, maybe the same thing but run sqlite in memory. Tradeoff is that if you’re not actually using sqlite in production then there are API and behavior differences compared to your real DB. Next option is mocking the database layer entirely, perhaps at the ORM level. It’s easier, you don’t have to deal with migrations, tests are quick. But the tradeoff is your tests are the farthest away from being “real”. So it all boils down to how much confidence do you want your tests to produce and how complex of a setup are you willing to put up with
Hey man, in the first test example, how can I test if my validation with class-validator are working? example: test if my response have a status code of 400 if no nome is provided, if the message contain "no name provided"?
I'm trying this, but I don't know how :(
I actually did cover exactly how to do that in the video towards the end, make sure to watch the whole thing 🙂
do you have an example using prism?
@Marius you can simply configure jest to use the same import strategy as vs code with the following config
```
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "./",
"modulePaths": [
""
],
"testRegex": "spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
```
Ahh thanks for the tip!
@@mariusespejo your welcome :)
@@mariusespejo Btw, have you found a way to use a vscode plugin to run the test? I would love to have a better interface for reviewing the test and see what values was returned and so on.
There is a jest vs code extension that I tried before that can do something like that but I wasn’t a fan of it. If you google vs code jest it’ll be the first result
@@mariusespejo I also tried that one out, but it is pretty slow compared to just using the cli tool, I was hoping I had missed some gold right in front of my eyes :)
Great video buddy. I wrote my first unit test for one endpoint in a pretty fleshed out backend API, and it was over 136 lines long. Is that normal? I imagine that if i do the rest of the endpoints in the controller file it will reach to 500 lines-ish
A controller unit test generally should be short. Most of your business logic should be in services/providers meaning a controller should be pretty slim and unit tests of it in most cases just need to assert that it’s calling the right service methods (which can be mocked). The endpoint e2e tests I would expect to be quite a bit longer because you’re integrating all the things including authentication, authorization, validation, middlewares, then finally asserting expected status codes and body response, etc. The e2e test is where you’ll get the most value, specially if you keep mocks to a minimum
@@mariusespejo thanks for the thoughtful response. I'll revisit the code and maybe try to get rid of sections. It makes sense as the controller only handles requests/responses.
GREAT. NICE JOB!!!
Great tutorial, really helped me with mocking my repository on the test file. I have really been struggling with it. I have a question though. How do I override a guard in my controller and also override a provider at the same time. I tried .overrideProvider().overrideGuards() but it didn't work and I kept getting the error "Property 'overrideProvider' does not exist on type 'OverrideBy'.". I would really appreciate your guidance on how to go about it. Thank you
You missing a few things there, you need to do something like this: .overrideProvider(MyService).useValue(myServiceMock).overrideGuard(MyGaurd).useValue(myGuardMock)
Basically you need to tell it HOW to do the override. I think there is also .useClass() as an alternative to useValue() if your mock is a class and not an instance/object
@@mariusespejo worked like a charm. Thanks alot, you literally saved the day 😅
Great!!
Hello, I have tried to do the video, but I try to connect to the DB all the time... my way is to simulate the service call, that
Please can you share your code or repo
Thanks. Your content is amazing
VS Code TS Auto-Import setting in preferences: Typescript > Preferences > Import Module Specifier. :)
Ah thanks didn’t know there was setting for that lol
@@mariusespejo I coincidentally had the same issue this week. Glad I could help.
That was really helpful for me. I discovered so many things about testing and now feel like I'm ready to write these tests. I have a question: what code editor theme have you been using during this video? ;) Isn't the Night owl?
glad to hear! yep it is night owl 🦉 Also have been trying github dark in some of my newer vids
great content!
thanks!!
thanks a lot for this guide!
glad to help!
Thanks You! Very Helful.
It would be nice to have a tutroial about NestJS Authentication, Authorization (Claims-based authorization) :)
I do have one for authentication in my channel
@@mariusespejo I've already seen a really good tutorial. Would be cool if you went even more deeply into the subject of authentification and authorization.
like RBAC and CASL
You were making integration tests but the file names had "end to end" is that right? I know it's just the name, but it confuses me a little bit 😆
technically speaking e2e IS an integration test, it just happens to to cover the entire flow end to end like from a user’s perspective them making a request and getting a response back
PASS src/modules/users/controllers/users.controll.spec.ts
● Console
console.log
debug: Logging initialized at debug level {"timestamp":"10-02-2023 13:00:10"}
at Console.log (node_modules/winston/lib/winston/transports/console.js:79:23)
at async Promise.all (index 4)
at async Promise.all (index 9)
my app when I running test. its pass the test but it not log the test text. can you help me.
Holy cow! its too good lecture. And I have a question. I am trying to do integration test. And my modules use axios. And then I got error which indicates that jest cannot parse axios. Can you give some suggestions on this ?
Nest has an HTTP module @nestjs/axios which basically lightly wraps axios and you make requests via HttpService, meaning it’s something injected and can be easily mocked in tests. Anything that you use directly will be slightly harder to mock unless you want to mock it at the jest level (which can also do its own module mocking) vs at the nest level
does this testing work same for both REST and GraphQL endpoints ?
yes should be mostly the same concepts for graphql endpoints but the key difference is for your e2e tests they will always be a POST with a request body containing the query
Very useful video, can you provide git repo
Easy and helpful
Is it possible to test the API with the database? Probably with e2e?
yeah I don’t see why not. You might want to use something that’s in memory though like sqlite or something and you’ll need to make sure the database is wiped for each test. You likely will also need to migrate and/or seed per test.
@@mariusespejo Thank you very much. The videos are great.
I'm having that same problem with the autoimport!! It's a pain
That said, E2E tests aren't usually meant to use a mock repository, but a fully provisioned test version of it that's as close to the production setup as possible.
I started working with NestJs very recently and love how it keeps the code organized, but it's not very helpful in creating integration tests, only unit (total isolation) and E2E (close to production). I supposed E2E tests do technically count as integration tests though, so it's not a huge deal either.
Yeah I would consider e2e as integration. Also you can run e2e tests with an actual db if you really wanted to, e.g. a sqlite for example, but you’d have to migrate/seed and wipe the db before/after each test. That added overhead/complexity may or may not be worth it depending on your use case or preference
can you share code in github ..?
Yo, thanks a lot for the video
no probs!
e2e is equal/same to integration test?
E2e is an integration test, but an integration test doesn’t always need to be end-to-end if that makes sense
Very nice!
please provide this video git Repo for more understanding
thanks for a video!
Is this a junior, mid or senior tutorial?
Are you asking about dev titles? Those honestly don’t mean anything in terms of your ability to learn
can i have the link to your github repo??
why are we doing this? Like we anyways implemented fake function and will implement functional in service that will contain bugs
You might be mocking the dependencies but you’re still testing that the logic in your functions are producing the intended results. The examples here might be too simple to fully see the value of it, I was mostly showing the HOW but I recommend reading about the WHY
@@mariusespejo okay thanks
Have source code in github?
thank you so much.
if you're making a mock service that has fake methods. what are you even testing? how is this useful?
Well the point of unit tests is to isolate and typically provide mock dependencies. Is it able to function in isolation? I’m just explaining how to do it. Whether or not that’s useful to you is up to you. But it’s the entire point of dependency injection, to be able to easily inject alternative dependencies (e.g. mocks in this case) I do think the e2e tests are where most of the value is, specially if you minimize mocks and setup a real db so that you don’t have to mock the queries. But you need a little bit more setup for that, e.g. you need to be able to reset your database for each test. How much you actually mock is ultimately up to you, e.g. how much of a unit vs integration test do you want to do.
Great
perfect man
tnx again
tnx
Yo
Sup
@@mariusespejo I don’t know about testing, should you be doing end to end testing with unit testing ?
useless without code//
You mean the code that’s recorded? Lol
You saved my day. Thank you.