We are looking for collegues

Mocking in JavaScript tests with Sinon, Mocha and Jest

Recently I ran into some issues with JavaScript testing in one of our projects. Since I had a hard time figuring out the solution and the internet didn’t help me enough, I thought I’d share my solution in a blogpost. The problem was that I had to mock AJAX calls done with jQuery or the fetch library. In this project we have 2 codebases where we use different frameworks for testing. One uses Jest for testing and jQuery for AJAX calls and the other uses Mocha and Chai for testing and the fetch library for AJAX calls. I will discuss my solutions for both frameworks. They are quite similar since I used Sinon stubs in both but there are some differences due to using jQuery or fetch. I won’t argue these solutions are the only ones or the best, I am pretty sure there are more (maybe even better?) solutions. Feel free to leave me a comment with your suggestions or remarks, I’d love to learn more!

Jest

First of all, we’ll start with the Jest framework. I was testing a React component that uses a separate class that has some helper functions to check if an account is logged in, retrieve the current profile and has a function to logout the account as well. I didn’t want to mock this helper class for all the tests in my testfile, only for my current running test. That is why I used Sinon to create stubs for certain methods of this class. This means some methods are mocked, but others are not. This can come in handy if you only want to mock certain methods.

In this case, we will test that if the user is logged in, but we cannot retrieve a profile, the user will be logged out. Since there must be something wrong and it’s best that the user logs in again. Here is a simplified example of the React component that we want to test including the AccountProfile class and the test itself:

As you can see in the test above, we use the setTimeout method before asserting that the AccountProfile.logout method is called. This is needed because the code is asynchronous. The test will fail without this. We also add the stubs and the spy before mounting the component. If you want to spy on a method on the component itself, this is essential. I would suggest to always put those methods first so you can never go wrong.

Mocha

Mocking the fetch call with Sinon and Mocha proved to be another challenge. Since this works slightly different, it took me some time and trial-and-error to get the tests working. In this case I was testing a method of a class in which fetch was used to get data from an api and then convert the data to an internal structure. I wanted to test this conversion. In hindsight I could have just used a callback method after fetch is done and test that, but I didn’t think about that option at the time. So I needed a way to stub the output of the fetch call to the API. Turns out this is possible, but it took me some time to figure out how. So this is how the simplified code looks:

The most important thing is to use window.fetch instead of just “fetch”. Since we are stubbing the window.fetch method, you need to use that in your code as well. This should work just fine. I had to add the es6-promise library because of the jsonOk function that returns a new Promise. Since the loadData method will return a promise, this is used in the test as well instead of the setTimeout method in the Jest example above.

Conclusion

These are two different frameworks for testing, although they look and function alike. The beforeEach functionality used in the Mocha example can be used in Jest as well and both examples use Sinon for stubbing (or mocking) the data. Since I have only been doing JavaScript testing for a few weeks now, I am still learning and exploring the possibilities.

I personally don’t have a preference in framework just yet, but I will keep on exploring both frameworks more in the future and learning more about JavaScript testing. I think this is a great addition to our PHPUnit tests which we write for the backend parts.