Mock vs Spy in Testing with Jest: Which is Better?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone in this video I'm going to talk about just there is specifically mocking versus spy so basically if you're using just for testing your application no matter in what level you might end up using MOX or spy and in this video I'm going to talk about how you can use any of them and what are the differences so let's just dive in and find out how we can achieve this so here in my package.json you can see I have just so just 29 and also the type for the gist I'm also using typescript so you can see there is a typescript here and and there's there's a types for the node.js as well and then we have rimraft to just really clean some package some directories nothing very fancy we have TS jest so to run the typescript and just together and then we have TS up to create the build and in my script I don't really have anything very fancy as you can see again we have a build which is really using tsop to build something and then we have clean which is cleaning lint which is linting and then we have test which is running just and that's all and if you go and look in a jest dot config you're using tsgist as a preset and the environment is node.js then we're going to transform it by this and then we are looking in the root The Roots is SRC directory and we are looking with anything with DOT aspect.ts okay this is just config so I'm going to close this too and now the next thing is I'm gonna go to source in the source we have two files so basically we have get user and a get user we really try to have like we just want to have a demonstration we want to have a function so it has a function which is get user and also you can see it receive an ID which is a number and then we return a promise to the user and then there is a console log and then if ID is less than zero it throws an error you can see the error is here and then it for example goes to a database get the user or find the user and then return the user now let's look at the find user so looking at the user we don't really do much anything here so we have a type and also you're checking if it's active and that's how we calculate is active basically by the ID and then assuming it's a database or something it's going to wait one and a half seconds I know it's very slow but just for demonstration then it's going to return the user assuming here you're going to call an API or call database or whatever it's just for a demonstration next thing that we're gonna do is write test ingest okay let's start with the mark it's very simple there now we have it described so you're describing something and then we are testing so when testing get user with a just mark it should return active user okay to begin with so first thing we need to do we need to just actually okay I'm gonna open these two side by side so we're gonna call get user so let's import it so here when we have get user now we can just let you check it so let's do it I'm gonna say const user equals actually yes user equals a weight and then get user I'm going to give it idea of 10. and then I expect then user actually there you go user.id at this case to be 10. because we are asking for ID of 10 so then if you look when it goes to the find user it's going to retain the actual ID but if you look at the username then it will be username and then space ID so let's also check for this one so I'm going to say username then to be username 10. okay let's run our test if you use npm Eon or anything there is no difference so we're going to use pmpm run test okay now you can see that when we are testing with a mock it should return active user now if I just call this one for example 11 the test should fail obviously okay yes because it was looking for 10. and also let's check for the active one active to be truthy so because it's number 10 the active is going to be true so let's run the test now one more time okay everything is fine we are passing the test but we are actually going to this um so from get user we are not mocking anything and it actually goes inside this find user and it run it to prove the point let's also put a console log here to make sure if you're here or not okay I'm going to just save this file now I'm going to run the code one more time you can see we are going to this line of code and we're running it in real life if you're going to call it if you're running unit tests and you need to just call a database or something it is absolutely better to just mock it because you are specifically in this case we are specifically testing get user function not find user so what can we do here we can use MOX or spy we're going to just see both of them and you're going you're going to see the difference as well the next thing that I need to do is to mock the user so what I'm going to do well what I want to mock actually is the find user function so I'm going to import that function is specifically find user from user okay that's the first thing the next thing that you need to do is to just say just dot mock and then you are going to Mark the whole things the whole file okay now I have mocked the file as well so you're going to import the function you're going to Mark the whole file inside the Describe You're Going to create a variable find user mock equals find user as so inside the describe we have this function as well so remember a few things first we have imported the function that you want to mock also we need to Mark the whole file and then we are creating a mock for that specific function so this find user is exactly what we want to Mark and then we are just casting it as just Mock and now we have a new variable so inside our test now what we have to do is basically we're gonna just call this one find user mock Dot so mark result value you have once or just resolve value whatever we want to do so if you want to just resolve it once we can do that one or we can do other things this time I'm going to actually return a user okay in this example we are doing a little bit different so you can see we created The Mock and now our mock we want the mark to return something different than the actual behavior of this one so let's have a look now also we have calling the user or just get user and we're expecting the ID to be 10 the username now it's going to be different because we're mocking and also we're not going to have here we're not going to have this console log to prove the point so remember here we have console log now I'm going to run it one more time let's see what do we get okay to begin with so we don't have that console log anymore so we only have console log from the main function or get user in the user we don't have anything and also because it's marked now the data that we get is different the username is not username 10 because we are mocking it we are just telling if you see this function mock it and that's what I want you to return so I want you to return mock username let's put this one here and test it okay you're happy now it passed the test it doesn't go to the function you can see we don't have this console log at all it doesn't go anywhere and everything is good the other thing that I really want to do is something like this I just really don't care about the username but I want to make sure once we are running this function once we are testing this inside get user I want to make sure find user has been called so let's have a look we can say expect and then here find user mock to be called times with or anything so I'm going to just say I want to make sure it's been called at least once okay so now you're checking for the username and active and also make sure this function was being has been called okay now I'm going to run the test it passes now if I just say for example 2 but we know we're only calling this one once now let's see what do we get on it one more time now you can see the received one was one but we're expecting two so that's it so now you can see the behavior of mock so we are importing the function that we want to mock then we will Mark the whole file then we will create a mock from that function by this line and then we are just really telling what is the expectation or what should mock return and that's pretty much it so this is mock you can see it's quite simple you just need to have a few lines and everything should work now I'm gonna go and work on spy on a spy exactly the same thing we want to return active user or inactive user to begin with we're going to have the same thing again so uh we're just going to call get user and also I am going to just copy these files and go here okay so it's pretty much the same thing I'm going to remove the skip so we can run the test and see what do we get I'm gonna also skip the just mock for now uh let's just save it go back here here we are just expecting so we are calling it user 10 we're not mocking or spying anything and then we are seeing the result so as you can see we have one skipped because we are coming to this function um we also see the console log because we are not spying on anything and it passes as well here it's empty test it also passed that one but let's ignore it for now but let's see how can we introduce Spa here the same thing is applied here as well so what we're going to do we're just going to say import Star as for example uh user functionality or user functions whatever you want to call it then from user so now we have if you look at this one it's importing everything as user function from the user file the next thing that I want to do is I'm inside the function I'm also going to do I'm going to say just here we're going to say just dot spy on so what do you want to spy on you want to spy on user function and what part of it we specifically one two so in this function it's because we are spying on this file we want to actually spy on fine user so I'm going to just do this one find user so we are spying on the whole things a very specific one a method or a function from this file and then dot here we have quite a few things so we can just say mock either change the implementation or just return something so we're going to say mock resolve value and let's just do it once and now this time I just want to return something different so we're calling for number 10 and that's what we want to return okay now this time if we are testing this you can see we are not actually going to this function anymore to prove the point so we have console log here we're just testing it actually I'm going to close this one here we should not actually see this console log because we are spying find user okay let's run the test okay this time you can see our test pass and we're gonna get a different what we're not going to see this console log to also prove the point again now I can just say user dot username actually to be spy username because we are spying now things will be different very good okay now you are sure that we don't go to this function and everything is fine I'm going to close this one that's how you actually write spy so spy is pretty much the same thing you are going to import everything with this format so you import everything as a star and then when you're going to look at the Spy is this way so you have just dot spy on and then you're looking at the whole things and then you look for a specific function or method in that object and then you mock it so you can just mock resolve mock implementation you can do a lot of things the other thing which is a bit annoying is here so we have a console log and I don't really want to see it so you can also mock that console log as well so it's very simple you can say just dot spy on what you want to um spy on so it's actually console and then I want to look into the log so if it was console.warn then you should use one here and what I want to do I just really just want to ignore it okay now I don't see any console log at all remember this line so we had console log get user now we're not going to see anything so I'm going to clear this one and then run the test happy days now we are spying on two things user functions and console the log one so you don't see anything obviously you have when you're running your test you can just pass silent and you don't see any log but that's how you're gonna adjust the spy and return something okay now we have spy let's just quickly fix the other one as well I'm literally going to copy and paste for the inactive one so let's just call 11 I'm gonna call 11 here we are expecting this one to be true because we are spying everything if I run the test it will definitely pass which is good but what I really want to do is I actually want to return false because really close to the expectation so now you can see it received false so let's just quickly fix it to be falsy and now if you run the test everything is good I'm gonna get rid of this this console.log now if you run the second time so here we are not spying on console and I'm expecting if I run my test for the second one so we have active one and then we have inactive one I should see this console log but let's see if it happened actually okay as you can see we don't see any console log because we spied on a console and now we didn't clear the Spy or Mark that's why we are seeing we don't see the console log so make sure if you're using um just mock or spy you clear afterward and if you want to do that you can achieve it in two ways you can say console console log spy console log spy then well you have created you have created a spy and at the end of your file all you have to do so we just run everything we are happy we just say console log spy dot mark restore so we have more Creator store this time because I restore the mock now we have exact behavior of console log after this line now when we're running the second time we should see this console log to prove the point let's see it okay good so we're not seeing the console log for the first one but for the second one we are seeing it one time and if I just remove the console log for both of them so we're not spying the console if you run our tests we should see the console log two times and we are getting it actually two times so that's one way of actually clearing or restoring the marks the other way is very simple as well so you can say before actually we can say after each so after every test that we're running in this describe what we want to do after each test what we want to do is to restore all the marks so now you are going to see a different Behavior now instead of just doing it one by one you're saying after every test just let's restore everything now I'm gonna run my test one more time now you can see I only see one console log why is that because here we spy on it on a second test we don't spy on a console okay now you can see exactly the different I'm going to open the mock and spine side by side and I'm going to just tell you or compare them together so at this stage let's talk about the differences so there are a few differences first thing is that with Mock You are going to import the function that you want to mock and then Mark the whole file create a mock and then manipulate the return value or implementation from the mock so you can see here we just because it's a sync function we are resolving if it wasn't you could just say mock return value mock return value once or anything that you want and then it would just returning that value on the other hand on the left side that we have spy we are just importing everything on that file like in this format Star as whatever you want and then you spy on that specific function that or method that you want to spy on so you just want to spy on find user from the user functions so user function is the whole things and then it's an object and then find user is one specific method or attribute or function in that object and then you just either resolve the value or change the implementation or just return the value add as it happens and also there is one more difference that we just saw with spy you can restore the mock and then after that that function will behave exactly the same as you know the actual Behavior so it's not mocked and it's not spied on but on the other hand on the right side on the mark you cannot do that so remember something with the spot you can just restore as you could see and with mock you cannot and also with the Spy you can just specifically spy on one function on the mark on the other hand everything is marked if you use this method but if you if you use this version but if you just want to specifically mark one function and leave the rest behave exactly the way that the behave in a code you need to use this version assuming you have a library and then you have database or DB so you're gonna just require the actual one so this is it just dot require actual so it returns everything but then from The Mark that's what you're going to return so you're going to return everything from actual but if you want to only for example uh mock a specific function not everything that's how you're going to do it so you are mocking one function which is this one is mocked the rest will behave exactly the same so that's how you're going to achieve only mocking one function from the whole file from the whole file in the DB but you can see the difference anyway now yeah mock or will give you less flexibility in some cases with the Spy you can restore you can just change you can do a lot of things and necessarily with spy you don't have to mock the behavior you're just waiting and listening or spying on that function and now I'm going to just remove this one for time being and also come in this line in case you want to use it later on and run the test one more time let's see what do we get there we go we get everything that we wanted so we have console log as I said you can just either also Mark the console here or here we just spied on and then the next thing that we do if you don't want to see it just put silent from just CLI and now you're not going to get any console log now you just know the difference between Mock and a spy ingest and in testing so thank you so much for watching this video If you enjoyed it please don't forget to share like subscribe to the channel which is going to help me and help the channel so much and also I'll see you in the next video
Info
Channel: Dev tips by MoHo
Views: 6,198
Rating: undefined out of 5
Keywords: npm, npm packages, node packge, jest, unit test, mock vs spy
Id: 9N8D7U9Am8o
Channel Id: undefined
Length: 25min 12sec (1512 seconds)
Published: Wed Mar 22 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.