NoSQL: A Complete Overview Of Testing Using Mocha

Udemy.com Home page wide-banner

In the last article of this MongoDB series, we have seen a brief introduction to how testing works using this technology and in particular how all rotates around the Mocha library and its featured function: assert().

Testing the students collection

As you may remember from how we left our application, we haven’t really done anything useful until now using Mocha since we only wrote some dumb examples using the assert() function. Now we are going to use our newly gained knowledge to test our Student collection. First, since we want to be able to access that collection, let’s include it inside of our testing file: creation-test.js: 

requiring the student model

Please notice this very important notion: 

When we require a Model inside of our file, we have to specify the relative path to get to the file where that model is being defined. 

So this implies that our require statement this time will be quite different since we need to specify how to get to the student.js file:

  • The “../” means: the folder we are currently in.
  • src: the folder where we defined the Student model.
  • student: the name of the file where the model is being defined, notice how there is no necessity to specify the file format.

Defining a new Student

Now that we have required the Student model, let’s use it by creating a new instance of a student:

creating a new student instance

Also here, notice a few things:

  • To define a new Student, we use the new keyword in combination with the Student model itself.
  • We pass an object to Student(), this object will be used to specify the values for the properties we defined earlier when we created the Student Model.
  • This instruction actually doesn’t create a new Student, in fact, to do that, we have to use another instruction that I’m going to show you now.

Saving a student

The instruction we need to use in order to save mathStudent is easy, and it has been provided to us by the Student model itself when we used it to create this object.

saving the student instance

To check if the operation was correctly performed, we will use Mocha. But first, let’s explore the effect of this operation using our favorite companion tool: RoboMongo. Connect to your local database (Windows user must be careful of having it started on your local machine). You should see on the left side of the screen the student_tests database, click on it and open the collections folder and then the students collection. This is what you should see: 

student saved output

Notice the properties, the name has the value we specified in our test file, and then we have a special _id property used to uniquely identify our document.

The saving gotcha

As often happens, we have to explore many problems that we could have when working with a new technology. Two things I would like to make you notice:

  • If you run the test on your app you will notice that Mocha will signal all the tests as passing, that’s because if no assertion is made the tests are considered as successful.
  • If you run the program again, you will notice inside of Robomongo that another Mark object was created. That’s the first gotcha we have encountered during this article. The fact that the database is not in a “clean” state when we are testing it is not a good idea. So let’s clean it up whenever we want to test it using something called a hook:

A hook is a function that gets executed before any test is actually performed. The beforeEach() function is the hook that we will use inside of our test_config.js file:

before each function

Let’s analyze this step by step:

  • Inside of the beforeEach() function we use the “mongoose.connection.collections.students.drop” function. That function uses a callback to then call the done() function
  • The done function is also included as an argument inside of the beforeEach function.

The callback function is used to address a simple problem we will encounter when writing this hook, how to let Mocha now that me have finished cleaning the database and that it can now start testing our project? The callback function addresses that, when entering its body, we call the done() function provided by every hook in MongoDB to tell Mocha: “Hey Mocha, we are done cleaning the database, now you can do your job”.

Writing the assertion

In order to complete the test, we can finally write the assertion that will be the core of our test. Since the save() operation is an asynchronous one, we will use promises to accomplish this.

testing saved student code

Let’s explain this:

  • As mentioned earlier, the Student model provides us some useful methods and properties that we can use with the various instances that we create. In this case we are using the isNew property.
  • The isNew property will be true if the object hasn’t been created yet, and it will become false once the mathStudent object gets saved. This allows us to determine if the object was effectively a new one or not.
  • We use the done function to tell Mocha that we finished with this test, and now we can proceed with the others. Also remember that the done callback can be used in every it() function, and that once that you include it as an argument to the promise its usage is mandatory.

Finally we have written our assertion and so we can check that everything was correct. Run the program and give a look to the logs of Mocha. You should get the test passing without any problems!

Here is the code in full for easy copy and pasting into your own project!

const assert = require('assert'); 
const Student = require('../src/student'); 
const expect = require('expect'); 

describe('student creation tests', () => {
    it('saves a student', () => {
        const mathStudent = new Student({name : "Mark"}); 

        http://mathStudent.save ().then((done) => {
            assert(!mathStudent.isNew); 
        }); 
    }); 
}); 

it('should match creation conditions', () => {
    const student = new Student({name : "Mark"}); 
    http://student.save (); 
    expect(http://student.name )
    .toExist()
    .toBeA('string')
    .toBe("Mark"); 
});

Bonus Section: Assertion libraries

Before leaving you at the conclusion of this article, I would like to spend some time to introduce you a very nice technology that you can use to test your applications: assertion libraries. Assertion libraries are basically tools to verify that everything is correct. In our case we can use this libraries to test the correct functionality of our code.

How do they differ from the normal assert function?

The advantage of using this type of libraries, is that they are:

  • Very easy to grasp
  • Extremely readable
  • You have a lot of choice, meaning you can choose the one that best fits your need, learn that, and add it to your cv.

Let’s see an example of assertion libraries using: expect.

If you click on that link you should land on a GitHub page with a perfect description of this tool and an amazing documentation to help you understand it.

Testing example using Expect

Let’s now see how we could write a couple of tests for our name property inside of the Student model:

First, let’s download expect using the usual:

installing expect libary
Notice the use of the @ to specify the desired version.
Now let’s say we want to test our name property for this conditions: 

  • The property has a value
  • The property is a String
  • The property has a specific value

This could be done like this in our creation-test.js file(remember to require the expect package before writing this code):

testing code with expect

Notice how this makes the testing code a lot more readable and easier to use. We now have a very explicit way of testing the student.name properties with a set of predefined functions that act like a series of assert().

From now on, feel free to use this library or others to test your code. It will be a major upgrade to your quality as a developer. Here are some other libraries you might want to check:

Conclusion

In this article, you have finally been able to connect the dots with the previous one and have a complete overview of what testing looks like using MongoDB and Mocha. You have also gained a great inside on other technologies to perform testing and how you might want to use them. Stay tuned for more articles!

Interesting Links

Keep up with me on twitter @BorrelliDev or check out my blog thecoderswag.com.

NoSQL: A Complete Overview Of Testing Using Mocha

You May Also Like

Leave a Reply

Your email address will not be published.