An Introduction To Vue Testing With Jest - (Realworld App)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey hey developers today we are gonna look at testing inside view j/s I'm gonna explain how you guys can get started with it I don't explain how you can use the wrapper and view test utils and we're gonna go over some basic examples and then a couple of examples that are a little bit more difficult to set up but we'll talk about it but before we get too far let's have a word from our sponsor hey guys when you're building your own website whether it's for yourself your business or a brand one of the hardest things to do is to find that awesome domain name that is short relevant and shows the world what you're all about which is exactly why I went and got view course tech which goes so seamlessly with my brand I'm currently using it as a really great website platform for my new view course and it's absolutely perfect join the likes of Viacom Intel and CES and get your very own dot tech at a whopping ninety percent off on one five and ten-year domains using the link go tech slash Eric it'll be in the description below only this Black Friday the sale starts on the 26th of November so you can pre-register now and get a further 10% off on the same day sale so make sure you go to go dot tech slash Eric in the link in the description below pre-register and you can get an additional 10% off thanks hey if you don't know my name is Eric I'm a full-stack software developer I'm also Manning author and I really like view Jas so you know view Jas is one of my favorite JavaScript frameworks out there I also am a big fan of angular and react as well so let's let's begin here this is our app that we created a few videos ago it's just a real simple app app where you can log in you can even register then log in and then you have the secret secrets area and I want to add a few tests to this and we're so we're gonna add some basic tests but first if you are completely new to testing a really good place to start with testing on view is to look at the view test utils guide so if you go to view - test - utils dot VJ s dot org you will get great introduction on how to start testing and really this is where you should start if you are beginning so this view test utils is a part of your app when you start and you create it from scratch usually this is a utility some you give you some utility functions that work with gest which will be what you use typically he can use mocha to inside your view apps to start testing so if you click getting started it's you can even download clone this repo the view test utils getting started and it kind of gives you some examples what the way usually the the way it works inside view tested utils is that you create a file you don't have to but you can create a file for each into each individual component that you're testing and then inside of it that file you do these describes and you do these its where basically you're describing what your tests what what file you're in a test and then you're you're doing assertions of what you want to test and you're you're doing setup code and then assertions and the way you do that inside using you test utils as you use this wrapper so now mount the component that you have the wrapper and there's something called mount and then shallow mount so this mount right here basically crates mounts the component for you and it also mounts any shell a child components as well while shallow mount stubs out all your child components so that's the difference between this mount right here in chin and shallow mount and we'll see that more as we move on and then it kind of gives you example of here of so once you have this component you have access to a lot of different things you have access to the HTML you also have access to dot VM which is a way you can access the data properties you can set data you can do all sorts of things and then there's this thing called next tick which is something that they recently became mandatory and it's still it's necessary when you want to advance the event loop so if you're doing so if you want it to trigger something and it's not working correctly you might need to use next tick we I'm not gonna get into do this too much but this is just really good to know that sometimes that you have Dom updates that you need to manually trigger the next tick in your test for it to work correctly and I like this it has a section on knowing what to test I think when you first start jumping the testing you see okay well I got it I got a test everything I got to do 100% code coverage I really like this that it says they don't recommend aiming for complete line based coverage so you're never going to have if you're new testing there's something called code coverage where it gauges what how many lines of code that you're actually testing like are you testing every single conditional in there and then some organizations have this 80% code coverage that you have to to hit but what happens is when you have these really hide code coverage and you have to keep it at a certain height you end up doing a you end up creating a lot of brittle tests it can really can create a lot of brittle tests not always because you're always yeah your is testing the internal implementation detail so you're always testing like what goes into this method do I expect this method to return this method but really what they recommend and a lot of people I think this movement for testing is going this way is instead of testing every single implementation detail every single method is that you just assert the components public interface and treat its internals as a black box so you can a good test would be like make sure that when the component starts it horse renders but maybe that way if you put some items in a input then when you click Submit that what you expect happens actually happens and that might be a better test than testing each individual method inside your component so keep that in mind so for example for the counter component which increments and displays a counter by one each time a button is clicked it's test case would simulate the click and assert that the rendered output is increased to one so that's that's kind of a that's what I see a lot of people testing nowadays instead of doing this really fine grained testing another really good utility to do this type of thing is Cypress it's more of an end-to-end test runner and you don't have X and when you're using Cypress the whole front end is basically a black box you can't change any values you're not going into the methods and setting anything you're essentially just running through the app from one end to the other and doing different tests to make sure it works we're not getting into Cyprus in this in this video there is I did some excellent Cyprus videos in the past maybe I'll put some links in the description below if you guys are interested in that that's another way to do testing and I know some organizations prefer more the end-to-end tests and some prefer more these more granular unit tests I think there's a place for both and as I mentioned before shallow rendering and it's essentially where it stubs out the any child components of it and you can do all sorts of things with emitted events which I'm not gonna get into and slots and and simulating props so that's the basics of getting started so let's let's see if we can get our app just do a couple of basic tests and we can see what we can do now if you start an app from scratch you will what typically happens is is you are going to get the option to adds tests so I'm going to just show you guys real quickly if I do view create I know Eric tests now I won't actually create this did you mean create yeah I forgot to e it's gonna give you this command-line interface to install to create your basic app right here it's going to ask you some defaults so I'm gonna menu select features and one of the options here is unit testing and end-to-end testing so let's say I select both of those when I'm creating my new view app and I hit enter now it's gonna give me asking me what kind of formatter I'm just say error prevention only Natanz save and here is where it's gonna ask you what your unit testing solution is there's mocha plus chai or just and it defaults if you just hit enter it we go through mocha mocha plus chai I'm gonna show you just in this tutorial here maybe in the future I think I've done some view tutorials for Moka in the past I'm sort of leaning towards more just nowadays because just has some really cool things that Moka doesn't have with snapshot testing which I'm not gonna get into this video but it is a possibility and also has some built-in code coverage stuff that I like so I think just is is really powerful but both of them have similar tooling to get started so you would click you know hit just here press ENTER and then it gives you the indented solution and so Cypress right now is chrome only which is one of the things that maybe is a big disadvantage I think they keep on saying one day it's gonna be multiple browsers and they don't they don't do that or you can use Nightwatch which is webdriver based I think in the past there was actually a different test and n test runner and I think they had a selenium based one I think this Nightwatch might be selenium based so essentially it's it's a way you can do your in an end-to-end end tests and you can have it'll act like it's in multiple different browsers I really like Cypress and you just hit Cypress here and I would go ahead and install everything I'm not gonna do that of course cuz I don't want to do that so now this app right here if you've been following along in my previous videos where I created this firebase app from scratch and I already installed everything I actually never installed any tests so if you look at the folder structure I have the source folder but there's no tests here but I can't install that manually so if I wanted to install this I could do it two ways I could do its to review UI and then search for the package or since I already know what it is I just go npm install and once again if you guys a yarn fans have at it and then you could add view and then it's called CLI plugin unit just and I put tack D at the end just to make sure it installs it as a development dependency obviously it's not a normal dependency so this is just take a moment okay so we went ahead and installed here now since I installed this I can actually run a command I can do view ad unit jest and that will get everything I need to start with if you're running this from View UI it'll sort of do it for you but since we're not so let's hear that view ad unit unit - chest and so now that should add everything in here so there's uncommitted changes current repository - commits - first still proceed so I do have some changes so I guess I should look at those so I'm gonna understand at them all and commit it dated and now I'm going to run the view ad just and what this is going to do is gonna add everything for the unit Jess is going to create some directories it's going to update my package.json file it's going to do a few things that we need to do to get started cool and see it says here it added the Jess config file it Anna added an example spec file it made some changes to my package JSON so that's exactly what I want it to do which is good one other thing we'll take a look at the changes a second but one thing also one install is this package called flush promises and this is a recommended package they recommend - you'll have to install this manually that doesn't normally come when you install that view CLI just plug in this will allow us to to flush the promises if we're dealing with asynchronous stuff which we do in this code base alright so we have all the packages installed so let's take a look what it added so if we look in our directory structure now we have this new tests folder and we have an example folder which nice of them they created our hello world app test file so all it does is it sends in a message which they call new message and then they just match it so they took we create this wrapper they do the shallow mount which once again that's shallow mounts when you create when you grab a component but you stub out any child components you can then have this object that you pass to it and you can put a bunch of different stuff in this app object so you can initialize your data object you can neutralize your props so in this case we initialize the prop so it's a message and then we just made sure that the data as I've sent through the props matches and it works correctly so that's what it adds there if you go into the package.json file you can see here it added in this test unit which is right here and what this does is it just runs your test cases so let's all minimize a hide control bar here and so let's do it let's just do npm run test unit and you can see here it's running and it'll pop up something here in a second after it's done running it should tell us if our one and only test case the example hello world is still working right cool so we can see here that it says hello world renders props message went when passed and as a little checkmark here and it all works and one thing I like to do when I do tests I like to keep it running in the background so I'm gonna put - - watch and this will make it just so it just continually runs so if I run that and I go back to my terminal and I run test unit now what it should do is it will keep this window open here and it'll just wait for any changes in the filesystem and if I want to manually run it I can type a and it'll tell us if our tests are working or a correctly or not one thing too is this jessa config file this just has the preset in here from the view CLI nothing else you really need to do in here we'll look at this later on maybe in a separate video where we can set up code coverage so that might be helpful so here's our one and only one this example spec file let's create a new file and let's let's test something else I don't know let let's start with I'm so a lot of my a lot of my components use firebase so we're gonna have to look at firebase to get everything working so but let's start with the I don't know the top header so I'm gonna create a new file called top header got spec dot yes I think that's the right yep top header now it's just ran everything again so you know I don't have anything in there actually it gave me an error that test suite failed to run your test we must contain at least one test so let's let's create one test for top header so do that I'm gonna you created a scribe and I'm gonna do top header top header dot view and first I should probably import it in so I'm going to import in the top header which if I remember correctly is my top header from and then I can use the @ sign and I can say it's in the components and top header dot view so that's where it is so now this has a function inside here and now I should be able to I should be able inside here to now create the wrapper and mount everything so let's do that so I have let's create a wrapper and I'm going to create it before each and what this does this will run every time before the test runs and I'm going with this wrapper here I'm going to do a shallow mount and so we'll need to import in shallow mount and that's going to be from the test utils which if I remember correctly that's from that view test utils okay cool and so now I'll be able to mount it correctly so to mount this I do shallow mount and then the top header which I just imported and this is now if you look at the documentation for view test utils there's the guide you can look at the API and you can look at shallow mount and you can see here it has some stuff you can go with so mount has of options let's see here I think there's some mounting options yeah so you can use this with a mount and shout them out so you have contact slots scope slot stubs mocks if we go back into here and we look at top header so we go to let's top header you can see it's a pretty simple thing it just this is the top header here just logged in no and it has a sign out button and it uses firebase and all it does as soon as the app loads it runs the created this created right here and it has a sign out button so with the created all this does is it checks to see if the user is logged in or not and sets a variable for it so what I want to do is I just want to see if this will create correctly but I want to do a little bit of refactoring here because I haven't found a way inside using view test utils to mock lifecycle hooks but you can mock methods so one thing I want to do first is I want to take this whole thing here I'm gonna grab it and I'm gonna throw it inside a method called and a set up firebase and I'm just gonna do the same thing it did before but this time I just want it to be out of the way and instead of calling it from the crew I'll call it from the credit right here so I'll do this dot set up firebase fireplace like that and that'll make sure and I'll make this look better that it runs correctly so now we have this top header here and we can do something like this we can do methods and I can do setup firebase and basically I'm mocking this out so it doesn't run the method otherwise I'm going to have to I'm gonna have to do a few things so this this this before each will run before it starts there and now I can create I can try to test something so I'm gonna say it renders so let's see if I can get this to render an ad and this render function should be just really simple all its gonna do is make sure that it exists so I'm going to do wrapper and well let's do this I'll do expect the oops add a expect and then the expect should have a wrapper in there and I'm just going to exists exists and that should to be true so let's see what our tested here so I'm looking at the run here said to past so I get it again yep everything passed as I expected which is good I can do W to show all run all tests yep so looks like everything's passing in those two tests cool so now we know that it renders but if I took out this message for setup fireface it's gonna give me a big old error when it tries to run yeah I can see here this wrapper it exists because it couldn't it gives me this big node modules hair because it treasure and this firebase off and it can't do it okay so we have at least the beginnings of testing the top let me delete this the beginnings of testing the top header but what happens if we want to check to see if a users logged in so if you look back in this top header we have this this on/off change and if it passes this user it gets passed and then this dot logged in equals if the user object exists that's a double bang here then it's true otherwise it'll be false so we don't want to test we don't want to like get into the nitty-gritty details of the setup firebase but maybe we can mock the firebase here in such a way that we can go in and do some really basic testing to see if this logged in user comes out true if this user object comes out true so this goes a little bit against what I just said earlier about not trying to test the implementation details but I think this is important because if you can test firebase is so popular you're probably not gonna be swapping out firebase very often that would be a major rewrite if you went from firebase to completely something else and we are gonna just test what happens when firebase returns true and that it's that everything works correctly so and that the logged in is set to true and if we look here at the top header if it's logged in this should say yes here in this span so we could check to make sure it says yes here so what would to do that really we need to mock firebase now this is getting a little bit more advanced stuff you well let's say first we can create another test here we just want to see before I jump into something that complicated I want to see if this div let's say this logged in here exists so we can do something like and really this should be let's say it's an h1 I'm gonna do some code changes here just because typically you wouldn't just have a logged in just floating right there without you know some kind of styling on it does h1 exist and to do that so I want to show you another property of rapper will he'll our callback or all of our function here and then we can do rapper we can we can do expect again and we'll have a rapper and by the way this is just a part of the this is how you expect things you're always trying to set up your test and then seeing if they work so if we do rapper dot find find can actually grab any sort of selector inside your inside your app inside your component so it's just like a CSS selector I can grab the h1 tag I can Gregg classes or whatever I want and then I can do stuff with it so if I want to grab the h1 tag which it's right there I can say rapper dot find dot h1 and then it can be 2 B and then I can have I can put you know some text in here so let's see if this works I've I just put logged in and make sure I comment I'm going to get back to firebase here so I don't get any weird errors there okay so it failed but it says object is equality so it received an object back from rapper dot fine h1 so I think it you can do rapper dot h1 find I think it's text maybe let's see cool so now it passed so now it doesn't have any errors there so now we grab the text from h1 and we choke and we check to see if it's logged in if I put in something wrong like logged in one it's gonna fail because it should be just logged in so we know to do that so that's gonna be some good tests if there was a button here like the sign out we have a sign out button we can always we can look for the button and use a trigger and then put in the event name to actually trigger this event too so sign out thing where we do the sign out and if it doesn't fail it automatically sets this user but let's let's let's try another test here I told you about firebase and how it's kind of a pain but we can mock out some of firebase and so I'll show you how to do that so to do that we can do jest and then let me make sure my autocomplete doesn't import something I should just and then it's doing mock and then if I look here the top header there's this firebase app and so you mock it like this with firebase app and then I can put an implementation that I want in here so we have this off and that's going to return an object and right now all we care about is we want to mock this on auth change on auth state changed so let's do that so we'll do on off state changed and that has a function in it there's a function passed in to it and then we return the function with true and so that's how I just quickly mock this out so this is a function you can see here on Austin's it has a function inside here and then it returns a value and if that users too or false depends if the users logged in or not so I'm gonna just to make it true so now we can since that's true there we should be able to go back in to our top header and see if this logged in is true or not so let's let's take a look at that let me scroll down so let's hear it let me say user is logged in after setting firebase Mach okay now so we're going to expect now we're going to use the rapper now the rapper also has if we go back to the documentation so you have this this is how you do all the mounts but if you look at I believe rapper there's the property rappers there is a whole bunch of things here's rapper there's a whole bunch of things that have so one of the main properties is a VM and VM is the the view instance itself and so there's tons of instances on the view instance self like dollar sign data dollar sign props dollar sign dl so you can really use that to your advantage because now I can do rapper dot VM I can do dollar sign data to get the data that's in the object and I can get logged in so if we go back to top header we see we do have this data we have this logged in and this should change to change to true so now we have logged in here now I can say to be you true so if I do this and just save it I fails because user logged in F setting firebase Mach it's coming back as false and the reason is that because we're just mocking it out right here and it's not doing anything as a setup firebase so I'm gonna comment this out so hopefully it should use our just mock right here I'm gonna close this so let's see what happens okay it's running a cool all for past so we don't have any errors nice so now just to make sure I did them out correctly if I put this to false it should return false and this should fail cool so it received false it expected true but received false so perfect so yeah so we we put it to true here but since we set the mock-up to return this false when this runs this comes back as false and thus logged-in comes back as false so cool so that works there I don't know what else could be testing this we could test clicking the Sign Out button to see if the sign out updates this replace and that we're going to this correct login page right here so what we can do to do that is let's try it so first we want to mock the router and so to do that you can actually do that through here so if you go back there's in shallow mount there is a couple of let me look it up here yep it's mocks and then you can put the mock for router and so these are only mocks for internal dollar sign values that are on the view instance that's where you put these mocks like router and since we haven't set up router yet we can we can do Const right here Const router and this this would equal the router that we want here so we can just do replace and a function here and now the router is being replaced it there with this router and all our tests are still passing there's no issue here as you see yep still passing so now we could do check to see on sign out move to route to correct place route to correct place so first we need to do is use the wrapper function we need to find the button which is right here and then click it so we can do find button and then we use this trigger and then we send a click event and that will click the button for us the next thing we need to do is make sure that once we do that it'll trigger this sign out and it's going to do this firebase off sign out so we're gonna have to mock the sign out as well but we could do that pretty easily so we have this on on off state change we can add in a sign out and that's actually going to return a promise and we're gonna resolve it so now the promise resolve will be resolved so now that's mocked out and let's see here our tests ran and yep I don't see any errors yet so that's good we don't really have anything so it triggered the click but it didn't it didn't really do anything after it triggered the click so now we need to see if it works so one thing I like to do sometimes is I'm gonna it there's a console log data here already in my app so I'm gonna put just put in a second parameter here test and when you look at my test to see do I see okay test undefined so we know that this came back correctly and that our router that everything just looks okay here so it came back as as test undefined so we know it ran correctly and didn't give any errors so now what we can do is we can see if what happened here so if we can expect and we can expect the router so we have this router here and it's replaced and really this is a mock that we can check to see if it's been called so one thing you can do is mock and I think it's calls let me check here what the right one is so what we want to do here is not using mock calls but I can do right or replace and I can do last called with and I can give it the object that was called so shouldn't called with this name a login so I'm gonna put name here and right here this login so let me put something wrong first and see if it works so it's testing okay so as it said of failed expected name login one but number of calls zero so it doesn't look like it thinks it was called at all so this is where we could try doing the flush promises so there is a flush promises that we imported in and so this will help us actually flush the promises out otherwise it thinks that it didn't finish so here's flush promise let me see if I can - yes I think that's right and it's flush promises so now up right here right after I do this trigger I'm going to just call flush promises and see if that fixes it okay so it says number of calls zero so still doesn't think it's was called oops I found my error here and actually what I need to do is make this async function and this flush promises I need to wait on it and if I do that then everything passed but if I change this to login one and I save it it fails because it expects named login so there we go change it back to login and it passes again cool so that's I think this is a lot of information to digest I think I'm gonna stop the video here so in the next video I'm gonna go in and test a few more things in my app a few more mocks for some of the other let me create another firebase app mock for the register and login components and show you guys how you can test that and if you guys have any questions make sure you leave a comment below but you know I think this is pretty neat all you can stuff you can do this with the shallow mount and the different expects and tests you can do and this flush promises makes things a lot easier when you're doing with asynchronous code and you need to make sure that things finish before you start testing them so let me know what you think in the comments below thanks
Info
Channel: Program With Erik
Views: 52,826
Rating: 4.737968 out of 5
Keywords: jest, vuejs, unit testing, tdd, Vue testing, Vue test utils, How to test vue apps, Vue testing 101, Vue test crashguide, Jest testing, JavaScript testing, Web Development testing, Vue testing 2020, Vue testing 2019, How to test firebase, Firebase testing, Firebase help, Program With Erik, Program With Eric, Erik Hanchett
Id: Fbo4pttBZ9k
Channel Id: undefined
Length: 38min 22sec (2302 seconds)
Published: Mon Nov 18 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.