Okay, so we are back in our code editor and I'm located in Lecture43 folder which is located in a fullstack-course5/examples folder. And herein you can see my Lecture43 folder is really the contents of that jasmine.zip unzipped inside of it. So I took the jasmine.zip, I unzipped it, took the contents of that folder that was unzipped and just basically dump it inside the Lecture43. Then there were couple specs here and a couple of the source files here, I erased those and I put my own in here. You could see that I'm looking at the SpecRunner.html and basically it's left exactly as it was before. All the script imports are jasmine imports. And you could see that I substituted these two lines and these two lines with my own script. First we have this CookieDetector.js, that's my source, we have this OddEven that we're going to take a look at also in my source. And we have a couple of specs One is CookieDetector.spec.js and the other one is OddEven.spec.js. Okay, so CookieDetector is pretty straightforward. We're going to write a function that given an array of some items is going to tell us whether or not a cookie is part of one of those items or not. So let's go to CookieDetector.js. And you can see I have several versions of this detectCookie function and you'll see in a minute why. So this CookieDetector takes an array of items. It loops over the array of items using this for loop, pulls out the item that is current iteration in the array, then tests if the item has the word cookie inside of it. And if it does, it will go ahead and return true. You could see here if it's not equal to -1 which means it does have the word cookie and it's some kind of an index. So you return true, otherwise it will return false. Okay, let's leave it at that and let's go to our CookieDetector.spec.js. Here you can see I'm describing, calling this describe function and calling CookieDetector as our string. And I'm setting up two arrays here, items without cookies and items with cookies. And the way I'm initializing those arrays is through this beforeEach function. You can see that I'm initializing the items without cookies, I have a bunch of fruit here. And items with cookies, it does indeed have the cookie string as one of the items in that array. Now, I really didn't have to have the initialization sitting inside a for each. Here, this is simple enough that it doesn't really change from test to test. So I could have just basically made it equal right here instead of here. But this is for demonstration purposes. And it's a good demonstration to see that you can initialize things right here. Okay, so let's try out our first test here. And it started with an it. And it should be able to detect no cookies. It means that I am going to go ahead and run detectCookie function with itemswithoutCookies. I'm going to pass that in, get the result and I'm going to expect, use the function called expect. That's a jasmine function and I'm going to pass the result to it and say not to be true. I expected it not be true because the cookies aren't there. The second one is it should detect cookies inside of there, it should be able to detect cookies because it has cookies in it. So let's go ahead and save that and I have browser sync running already. Let's go to our page here and we'll click on the SpecRunner.html. When we click that, we see we have a failure. First of all, we have four specs. But we don't need to look at that list yet and I guess we could look at the list. We have a whole bunch of CookieDetector and then OddEvenGenerator, we'll look at that later. But you could see that one of them is passing, it's green and the other one is not, it's red. This one says, should be able to detect no cookies, that one seems to be passing, but should be able to detect cookies is not passing. So therefore, we go back to the code and take a look at our CookieDetector. And if you notice, our false statement is actually sitting right inside the for loop and that's wrong. We really need to take that return false statement and put it outside of it right here. The funny part is is that I didn't do this on purpose. Maybe that's an embarrassing thing, but I didn't do this on purpose. I actually wrote this function very, very quickly and just whipped it out. And didn't really look twice at the fact that I stuck this return statement in the wrong place. And then wrote the spec and then ran the spec and saw that it was not passing. And therefore, I had to go back and look at the code. And that's really a perfect example that even somebody who's experienced can make really stupid mistakes. And these stupid mistakes don't come out until much later. Because remember, the first test passed. Which means that if I had a whole bunch of lists with no cookies in them, which is a horror into itself. It would've returned no cookies and everything would've been fine. I wouldn't have noticed anything until I finally passed in something that did have cookies in it and it would've failed. It would've told me the wrong thing. So let's go back and I actually wrote, instead of erasing it and changing it, I just commented it out and wrote a version two. Once again I was very quick to just slap it together without thinking twice about it. And when I wrote version two, so the version two now moves the return false statement outside of the for loop, so let's save that, let's go back to our browser. And you can see, we'll still not working here. It says expected false to be true, which means it's returning false when really it should be true. The CookieDetector should be able to detect cookies. Let's go back and take a look as to what's going on here. And I'll go ahead and comment that out, and we'll go to, actually this is version three, not version four. And we'll comment this out and the reason this wasn't working properly. Was because I forgot that in my CookieDetector or in my cookie spec I should say, I have these cookies with a capital C. So capital C doesn't really work unless you first lowercase it and then compare it to the cookie which is all lowercase. And in this case if I go and save it, go back to my browser, you'll see that both tests now are green which means both tests are passing. And this is really a perfect example of how you should always try to test even the simplest code you have. You exercise your code and stupid little mistakes come out that you could fix now. Instead of having to have a whole investigation process later as to why your entire application is failing when it's really just a small minor mistake. And if you tested it at the unit level, the smallest level, you would've detected it. Okay, let's go back to the code editor and let's see one more example. And the one more example is this OddEven.js. What this OddEven.js does is called the getRandomOddOrEven1to10. So this function will return to me a random number from 1 to 10 and it takes the type as one of its arguments. Which means I could tell it whether or not I want an even number or an odd number but I want them to be a random number. Now the way we achieve it, is by having a random number generator pass to us as the dependency into this function. True we could've had this random number generator right inside this function. But it's much better to separate the two because those are two separate functions. This one has to return a random number from some number to some number. That's something that you could definitely make a mistake in and you want to test separately. And this can also make mistakes in how it figures out whether or not the number returned is an odd number or even number. So how are we going to be able to test this method with this function independently from the getRandomNumber. I do not want test the random number right now. I just want to test whether or not given that the random number works. Assuming that it works, does my getRandomOddOrEven1to10 function work? And here's how I'm going to do it. We're going to use a mock. We're going to go to our CookieDetector. Wrong one, the OddEven.spec.js. And the way we're going to do it is inside beforeEach, we may declare randomNumGenerator8 and randomNumGenerator3. This one obviously is going to generate an 8 and this one is going to generate a 3. So we're going to grab a random number generator, it expects to from, the getRandomOddOrEven1to10 will pass a one and a ten right here. But that's not going to matter because we're faking the response and the faked response is going to be eight. So whenever this random number generator gets called with the arguments of to and from, it will still always return an eight. And the same thing for this one. It will always return a three which means I know that will always return an odd number and I know that this one will always return an even number. So if I go to my it Function, I could see here should produce an odd number. And I call the getRandomOddOrEven1to10 function and I pass it the type odd. I want an odd number and I go ahead and feed it an odd number that my randomNumGenerator. Will be faked to feed the getRandomOddOrEven1to10, it will be faked to feed it an odd number. Which means I should get that number back to me and that's what the result should be. So I expect the result to equal three and the same thing should produce an even number. I'll just pass an even here and feed it number eight as the random number and that's the first number that shows up. I should get it back and therefore my result is expected to be eight. If I go back to my browser, you'll see that both of them pass just fine and you can see that you can click on each one of these tests if you need anymore details. In this case, they're passing. So there's no more details. So I could click on all of them and all of them run. Now let me show you another one very quick thing. For example, if you're not ready to test something. Let's say test something is broken or you need to get back to it and the tests are failing. A quick way to take one of the tests out of the running is simply to put x right in front of the it function. So right now if I save this, this should produce an even number test will not run. So let's go back to our browser. You could see that it says, should produce an even number pending with message temporarily disabled with xit. And the same thing actually applies if I wanted to put an x right in front of describe and save that. That means the entire OddEvenGenerator suite of tests, all of these tests right here will be temporarily disabled. So if I save that and go back to my browser, you could see that both of them are now kind of yellowish or beige indicating that they are both disabled. And you can see up here it says that there are four specs, but we have two pending specs because I disabled those. So I could go back and actually maybe just remove this x, but leave this x right here just for your reference as to how to get that done. Okay, so let's summarize. Remember that unit testing is an essential process in any software development. And planning for unit testing changes how you write your code for the better. It almost forces you to be more unit oriented and therefore a right smaller chance of code and smaller pieces of functionality that only are responsible to do one focused thing. And that's always a good software development practice. Now mocks are used to fake the dependencies of our target code. And that so we don't have to bring the entire car so to speak just to test one tire. The way you define test is by starting to group them together using the describe function. That takes a message in a function that contains the rest of the guts of the entire specification. Now inside of describe function, you could call the beforeEach function also providing it yet another function as the value of it. And that's used to initialize state before running each test. Therefore, making sure that you have a well known and established state of your system so to speak before you run any test that assume that that state is intact. The actual test is performed with the it function. It takes a message and a function where the actual testing and verification code is contained.