Unit testing is one of the best ways to uncover hidden bugs in your applications. In this day and age, the ability to write a good unit test is not only a requirement for a programming language, it’s an essential skill for a software developer as well.
Let’s navigate to our terminal. Since I’m on a Mac, I need to execute a Sudo. npm install -g, mocha. So this will install a Mocha Testing Framework globally so that you can run tests in any of your application projects. To run a Mocha test, all you do is type, “mocha.” And the first thing that you’ll see, is that we cannot resolve the pattern or path ‘test’. That is because Mocha is looking in the test directory for all of its tests.
I’m going to go ahead and make a test directory, mkdir test. will now make a test directory. And I will clear the screen, and I can type, “mocha” again, and now we can see that it is not complaining about a missing directory but we don’t have any test. Let’s go ahead and write our first Mocha test. I’m going to go ahead and open up Sublime and the first thing I’m going to do is create a new file and I’m immediately going to save it as tools-spec.js but I’m going to make sure I save it to the test folder. So we’ll go ahead and save our test file there.
And we are going to participate in test-driven development. That means that we are going to watch the test first, watch the test fail, and then write our code to make our test pass. So, I’m going to use a Mocha function called “describe.” And the describe function is what we would use to set up a suite of tests. And I’m going to describe our printName function. So we are going to go ahead and test a function called printName, and the second argument for the describe function is a callback function. And this is where we will actually write all of our tests for printName.
So each test, we will use an ‘it’ function for that. And we are going to make sure that the printName function will take in a person object, and print their last name first and their first name last. So, it, “Should print the last name first.” So, there is our first test. What I’m going to go ahead and do is save this tool spec and I’m going to navigate back to the terminal and let’s try to run our test again. This time, Mocha found our spec file in the test folder, and you can see it created a suite for the printName function.
It has colorized our pending test turquoise. So you can just use the it statement to go ahead and stub your tests. So now, lets go ahead and write the printName test. We are going to take part in test-driven development. Which means, we are going to write the test first, run the test, watch it fail and then write the code to make the test pass. So, what we are going to do first to write this test is we’re going to need an Assertion Engine. Mocha gives us a Suite for describing, running and building tests but it does not give us a way to check values.
That is where you might want to consider using Chai. I’m going to go ahead and install Chai locally to this project and I’m going ahead and send it a save-dev flag. And the reason that I’m going to save Chai to the Dev dependencies, is because Chai is going to be needed to test our application. Our Dev dependencies are where we save the things that we need to work with an application where our main dependencies, save those packages that we need for the application to actually run.
So, I’m going to go ahead and install Chai. So that we can use it to check our results. And let’s go back to our test file. And let’s include Chai. I’m going to go ahead and say there, expect = require (“chai”).expect So we are going to be using the expect function of the Chai Assertion Engine. Chai also has the ability to use the Should Assertion Engine as opposed to the Expect Function, and then you also have the ability to use Assert.
Those are just three different styles of assertions that you can do with Chai. What I’m going to go ahead and do is add a second argument to this it statement. This is the function where we actually code the test. Now in order to test the printName function, we actually need a printName function. So, what I want to do is include a set of tools. var tools is going to be the module where the print name function lives. So I need to require my custom module. Now I haven’t built this module yet, but I’m just deciding that this is where we are going to store the printName function.
So, I think this module is going to be out of the test folder in the library folder and we’ll call it tools when it is finally time to create it. So we have a module called tools, and in out tools module there is a printName function. When we write a test we simply want to invoke the item that we are testing. So, I’m going to create a variable for results. And I’m going to invoke the printName function. So, I don’t have a printName function yet but Ideally, if I create this function, this is how I would like to work with it. I should be able to sent this function an object that represents a person.
This person should have a first name and I will go ahead and use my first name, and a last name. I will go ahead and use my last name. And if I invoke this function, printName, I expect it to return a string with Banks first and Alex second. So, this is where we use that Expect Function. So, I am going to expect my results to equal and the printName function should return Banks, Alex. So, we are going to check the results, to see if it works appropriately.
So I’m going to go ahead and save this test and go back to the terminal. I’ll clear this previous terminal text, and I’m going to go ahead and run Mocha. And this time you’ll notice that we get an error. So, we cannot find the module, library tools. So, one of the things that we need to do is we actually need stub the function that we are going to test. I’ll go ahead and clear this screen. And in order to do this, I’m going to navigate to Sublime. I’m going to immediately create a new file. And I’m going to immediately save this file as tools.
So inside of my Library Folder, I’m going to make sure I put it in my Library Folder. I’m going to create a file called tools.js And what I want to do is export a literal that would have all of my tools. So the first tool that we are going to use is going to be my printName function. Notice, this is how I am defining the printName function inside of this object literal.
These are called Object Literal Enhancements. and they are a new way of definding functions within an object literal that is available to us with ES6. Since we are using Node.js version 4.1 and up, we can use some ES6 syntax. So, I’m going to define my printName function like so. Now, I’ll go ahead and save this file and go back into my terminal. And let’s try to run those test again. So I’m going to type, mocha. This time we see our printName test failing. So, we know that it finds the printName function, but the printName isn’t returning anything now.
It’s returning undefined. And so, this is showing us that we have an assertion error. We expected undefined to equal Banks, Alex. Let’s go back to our tools, and now let’s write the code that we need for this function to pass. So, this function is going to take in a person and it should return a template string for this. And what I’m going to go ahead and do is select the person.last name and add a comma, and then also select the person.first name, and we will add that last.
There we go, so my printName function is going to print the person’s last name first and the first name last. Let’s go ahead and save this, and navigate back to the terminal, and let’s try to run our test again. This time when we run our test we can see that it is passing. The printName function is behaving as expected. We have completed writing one Mocha test participating in test -driven development where we wrote our test first, and then we wrote the code after the test.