Blog.

Jasmine vs. Mocha

MF

Marco Franssen /

7 min read1274 words

Cover Image for Jasmine vs. Mocha

In this blog post I want to highlight the similarities and the differences between Jasmine and Mocha. In this comparison I will focus on the latest versions of both libraries. As of this writing Jasmine 2.4 and Mocha 2.3.

When comparing both libraries at NPMCompare you notice that Mocha is the more popular framework today. Mocha has more frequent updates, more downloads and more forks on Github. Although both frameworks are pretty popular and do have a lot of similarities. Lets go have a look at some more details of both libraries.

Similarities Jasmine and Mocha

Both libraries have a similar API regarding the structure of your tests. They both allow you to write your tests using a describe block. They also both have the same approach for asynchronous testing using a callback method (done). In the next code example you can see the similarities between both the frameworks.

describe("User", function () {
  describe("When getting the users details", function () {
    it("should contain the full name", function (done) {
      // assertions go here
    });
  });
});

Please note that the asynchronous behavior is only the same as of Jasmine 2.x. In Jasmine 1.x you had to use methods like waitsFor to write a test that required asynchronous behavior.

Both libraries are also supported in the popular test runner Karma. Karma can run your tests against different browsers like, Chrome, Firefox, PhantomJS etc. It can watch you tests and source files for changes and automatically run your tests against the browsers you configured in the config file. This gives you continuous feedback while developing your code.

Differences Jasmine and Mocha

Assertions

The differences of both libraries start where you are doing your assertions. Mocha does not come with a built in assertion library. There are several assertions libraries available for Mocha:

  • Chai
  • should.js
  • expect.js
  • better-assert

It seems many developers choose Chai as an assertion library for Mocha. So where you can use Jasmine as is to write your tests, you will have to load another assertion library with Mocha. Lets have a closer look at Chai as I have some hands-on experience with this assertion library. Chai comes with three assertion styles, the should, expect and assert style. The expect style is similar to Jasmine and is therefore the easiest to migrate from Mocha to Jasmine or the other way around.

Jasmine
expect(calculator.multiply(3, 4)).toEqual(12);
Chai
expect(calculator.multiply(3, 4)).to.equal(12);

Mocking

Mocking in JavaScript comes in the form of spies. A spy is a function that replaces a function from your code where you want to control its behavior in a test. You could for example record on how such a function is used in your test to do some assertions based on usage. Some more concrete examples are:

  • Count how many times a spy has been called
  • Specify a return value to have your code follow a specific path
  • Throw an error to test the exception flow
  • Inspect the arguments a spy has been called with
  • Have the spy call the original function, this is not by default. (This enables you to count for example the calls to the method and still execute the original logic)

Also for mocking Mocha does not come with built in mocking. If you want to use mocking/spies with Mocha you need to use another library called Sinon. Sinon is a very powerful library which is equivalent to Jasmine spies with some additional features. In Jasmine you can create a spy like this:

// existing methods
var blogPostSaveSpy = spyOn(BlogPost.prototype, "save");
// non existing method spy
var spy = jasmine.createSpy();

Sinon has three different approaches to apply mocking. Spies, stubs and mocks, each of them have some subtle differences. For example a spy in Jasmine will not call though on the method being spied, where in Sinon this is default behavior. A small example:

Jasmine
spyOn(blogpost, "publish").andCallTrough();
Sinon
sinon.spy(blogpost, "publish");

A sinon stub has equal behavior to the default behavior of a Jasmine spy. Example:

Jasmine
spyOn(blogpost, "publish").andReturns(200);
Sinon
sinon.stub(blogpost, "publish").returns(200);

In many situations Jasmine spies will cover all you need with regards to mocking. In case you need a little bit more features you can however also use Sinon with Jasmine.

Zooming in on the asynchronous tests

Asynchronous tests will be useful for all you code that does Ajax calls or in case of Node.js goes to the database or file system. In those cases you need to inform both Jasmine or Mocha that your code finished executing. Two examples of asynchronous code is code with callbacks or Promises. In the following code example I will show you how to use both approaches in an asynchronous test. Imagine the Blogpost.getById method returns a promise which resolves with a user object. The following example code uses Bluebird for the promises to have some syntactic sugar like the catch and finally methods.

Promise
describe("When loading a blog post from database", function () {
  it("should return an instance of Blogpost", function (done) {
    BlogPost.getById(1)
      .then(function (post) {
        expect(post instanceof Blogpost).toBe(true);
      })
      .finally(done);
  });
 
  it("should return the user with id 1", function (done) {
    BlogPost.getById(1)
      .then(function (post) {
        expect(post.id).toEqual(1);
      })
      .finally(done);
  });
 
  it("should fail with a 401 for non-existing posts", function (done) {
    BlogPost.getById(2)
      .catch(function (err) {
        expect(err.status).toEqual(401);
      })
      .finally(done);
  });
});

Notice that we use the finally statement to call the done function. By doing this we are sure the done method is always invoked, even if the test fails (basically caused by not going into the then or the catch).

Callback
describe("When loading a blog post from database", function () {
  it("should return an instance of Blogpost", function (done) {
    BlogPost.getById(1, function (err, post) {
      expect(post instanceof Blogpost).toBe(true);
      done();
    });
  });
 
  it("should return the user with id 1", function (done) {
    BlogPost.getById(1, function (err, post) {
      expect(post.id).toEqual(1);
      done();
    });
  });
 
  it("should fail with a 401 for non-existing posts", function (done) {
    BlogPost.getById(2).catch(function (err, post) {
      expect(err.status).toEqual(401);
      done();
    });
  });
});

Note we are invoking the done method after we did our assertion, to tell Jasmine/Mocha the asynchronous code finished. Also note we have been using Jasmine in this example (you can see that based on the assertions). Obviously you could have achieved the same using Mocha, as the way of doing asynchronous testing is exactly the same for both frameworks.

Wrapup

Overall I think you have a little more flexibility when using Mocha, since you can pick your own assertion library and your own mocking library. This however also comes with a price of a slightly more complex setup and some additional dependencies. Overall I think it depends on each project or your personal preference which of these libraries you want to use. When using Jasmine this does not exclude you from using Sinon. You can still benefit for example from its fake server. Both frameworks are perfectly able to do the job. As of Jasmine 2.x, I think Jasmine is back in the race with Mocha.

Also consider reading one of my previous blog posts:

In this blog post I have some more detailed examples on how to use Mocha with Chai assertions and Sinon Mocks. Thanks for reading this blog post. I hope it was useful for you. Please leave me a comment in case you have questions or remarks.

You have disabled cookies. To leave me a comment please allow cookies at functionality level.

More Stories

Cover Image for Ssl certificate for your Azure website using Letsencrypt

Ssl certificate for your Azure website using Letsencrypt

MF

Marco Franssen /

Letsencrypt is a free automated service which provides you SSL certificates for free. Although the certificates are only valid for 3 months, this shouldn't be a bottleneck as you can fully automate the certificate request and renewal. Letsencrypt comes with a python client which you can use to make a certificate request. Letsencrypt can be ran from a Linux OS. In this blogpost I will show you how to use the Letsencrypt Vagrant box (Ubuntu vm) to authorize the certification request for your Azur…

Cover Image for Switch between Hyper-V and Virtualbox on Windows

Switch between Hyper-V and Virtualbox on Windows

MF

Marco Franssen /

Since a while I have been using Virtualbox + vagrant to do web development based on Linux, Nginx and NodeJS. However I also still do Windows development occasionally. For that reason I needed a way to easily switch from Virtualbox to Hyper-V or the other way around, as Hyper-V is required for example for the Windows Phone emulator. Hyper-V can not run together with Virtualbox as they both need an Hypervisor. Unfortunately you can't have 2 Hypervisors running. Therefore we need to disable Hyper-…

Cover Image for Put your ssh experience in Windows on Steroids

Put your ssh experience in Windows on Steroids

MF

Marco Franssen /

In this blogpost I want to show you how you can make your life easier to work with Linux VM's and Git by configuring SSH on your Windows Machine in a secure but convenient way. Let me first elaborate a little further why you would want to apply the tips and tricks from this blog post. Git has become the de-facto standard of vcs over the past few years. You are probably using it for all your software development projects, and maybe even for your web blog, when you are blogging in markdown using…

Cover Image for Using Gulp.js to check your code quality

Using Gulp.js to check your code quality

MF

Marco Franssen /

In this blog post I want to show you how you can use Gulp.js to automate some tasks to check the quality of your code. Before we deep dive into the subject and the coding examples I first want to give you a short introduction on what Gulp.js actually is. So if you already know what Gulp.js is about you can move on to the next chapter. Easy to use By preferring code over configuration, gulp keeps things simple and makes complex tasks manageable. Efficient Using the power of node streams, gulp gi…