Testing ES6 Promises in Node.js using Mocha and Chai

Will Button
InstructorWill Button

Share this video with your friends

Send Tweet
Published 6 years ago
Updated 2 years ago

Writing great ES6 style Promises for Node.js is only half the battle. Your great modules must include tests as well to ensure future iterations don't break them. In this lesson, I show you a simple ES6 Promise in Node.js, then walk you through creating tests in Mocha using chai and chai-as-promised to test both resolve and reject methods.

[00:01] Let's take a look at the function I have on the left-hand side of the screen. It returns a promise, and if the parameter we supplied to the function is a one, it's going to reject the promise. If we supply any other value to it, then it will resolve the promise. We need to write some unit tests to ensure that this behavior remains the same.

[00:23] We need to do a little set-up to get our system ready for tests. I have Mocha installed already, but if you don't have Mocha installed on your system, you're going to want to install it with the NPM Install Mocha command. I personally used a -g flag, so it's just installed globally on my system.

[00:43] We're also going to need a package called Chai that we're going to use for testing. I want to save that to the package.json file, as a development dependency. We're also going to use one called chaiAsPromised, which is an extension for the Chai library that works with promises. We'll save it to the development dependencies, as well.

[01:07] Over in my Project folder, I'll create a new folder called Test. Inside of that, I'll create a new file called Index_test.js, because it's going to be used to test the Index file. I need to set up some requirements here, so I'm going to create a reference to use the Chai library. I'm using the Expect syntax, so I'm going to let Chai know that and I'm going to include the chaiAsPromised.

[01:40] Also include the file that we're going to be testing, which is my index.js. I'm going to call that Index. Finally, I'll tell Chai to use the chaiAsPromised extension. Now we're ready to start writing our tests.

[01:59] I'm going to create my first describe block, and we're going to describe the function foo. Our first test is going to say it should resolve any number except one. Then I'll define a promise, which is going to be a call to the foo function inside of the Index file, and I can pass in any number except one. Then we'll return and declare our Expect statement and expect that promise to eventually equal zero. That should be Expect not Accept.

[02:39] This is where the chaiAsPromised comes in. This Eventually keyword comes from chaiAsPromised, and that's because we're dealing with a promise here. It doesn't return immediately, so your standard testing syntax won't work with promises, because the value you're expecting isn't there right away.

[02:58] Let's test this and see how it works. We'll do Mocha test Index, and it passes. Is that right? Is that certain? Let's test it and see. What if we give it a two? That doesn't work, and that's because we specified when we called it index.foo, we provided a zero and it returned a zero, and we set the expectation to two. If I set this to two here, and then run that again, it's going to pass.

[03:32] We have one more test that we need to write for our function. If we supply a parameter of one, it's going to reject that promise, so we need to write a test to ensure that that's going to happen. We're going to write a test that says it should reject when supplied a one.

[03:52] We'll define another promise, which calls our Index.foo function. This time we're going to supply one as the parameter, and then we'll return that to Expect, pass in the promise. Then "to be rejected," is what we're looking for here. If we run that, we have two tests that are passing. Just to validate that, if we supply zero, it's not going to be rejected, so our test should fail.

[04:24] It does fail. Let's change that back. We can take this one step further. We can say that it is rejected, but it is also rejected with a specific error. If we look back at our code, we reject it with the message "found an error." We can actually provide that error message here and, when we run our tests, validate that not only was it rejected, but it was rejected with the correct error message.