Testing

Tips and tricks for mocking in JavaScript tests

Daniel Verner -

In one of my previous posts, I wrote about unit testing in JavaScript (you can find it here: https://42coders.com/unit-testing-javascript-with-jasmine/). When doing TDD (test-driven development) or BDD (behavior-driven development), it is necessary to mock the input of the tested methods. If the code is clean enough it should be pretty straightforward to do, but in some cases things get complicated. In this article, I’ll show some tricks on how to deal with these scenarios.

Datetime
When a function uses the built-in DateTime object, we’d need to find a way to mock the built in time object. It could also be solved by refactoring the function to take the DateTime object as an argument, which would make the mocking trivial, but it is a subject for another article. Let’s see how can we solve the problem described above. I’ve used sinon.js https://sinonjs.org/ a cool library that is capable of fake timers, xhr requests, and much more.

Install sinon using npm:
npm install sinon
Require it before usage:
let sinon = require('sinon');
Create a date object to use a fake timer:
let fakeDate = new Date(2019, 5, 11, 12, 0, 0);
Use the fake timers:
let clock = sinon.useFakeTimers(fakeDate);
When the desired test has run, restore the timers with:
clock.restore();

Geolocation
Geolocation enabled apps are not easy for testing, especially because good quality GPS signal can be captured only outside. From fitness and health viewpoint it would be good to write some code and walk a bit outside for testing, but the productivity won’t be so good 🙂

You can mock the HTML5 geolocation with the geomock library: https://github.com/daniel-werner/GeoMock. I’ve forked this repository from https://github.com/janmonschke/GeoMock, and only added one feature, to send the predefined coordinates only once, without repeating them.

First of all require geomock
require('geomock/geomock');
Set up the time interval to send the coordinates (in milliseconds)
navigator.geolocation.delay = 1000;
Set up if it should repeat the coordinates or just “play” them once.
navigator.geolocation.repeat = true;
Add the predefined coordinates
var startTime = 1551018055000;
navigator.geolocation.waypoints = [
    {coords : {latitude : 45.8849114, longitude : 19.2545559, accuracy: 65 }, timestamp: startTime},
    {coords : {latitude : 45.8856601, longitude : 19.2553514, accuracy: 65 }, timestamp: startTime + 30000},
    {coords : {latitude : 45.8849114, longitude : 19.2545559, accuracy: 65 }, timestamp: startTime + 55000},
    {coords : {latitude : 45.8856601, longitude : 19.2553514, accuracy: 65 }, timestamp: startTime + 75000},
    {coords : {latitude : 45.8849114, longitude : 19.2545559, accuracy: 65 }, timestamp: startTime + 90000},
];
When the tested code uses the geolocation feature, it will get the fake coordinates, and you’d be able to test it easily. Using this library can be beneficial for creating integration tests or feature tests of the application.

Writing tests for existing code
In some cases, you might write tests for existing, working code. This is not considered as test-driven development, but it is much better than not having tests at all, and the tests can ensure you won’t break existing functionality when modifying the code. But writing tests is boring, writing mocks are even more boring, and we developers are lazy :), so we’d use tricks to avoid doing boring things. My favorite trick in these situations is to test the code manually and copy the function’s arguments during this test. It is easy to do with the Chrome developer console, the following way:

Add console.log(argument1) to the function.
Open the console in the DevTools, right-click on the logged data, and select Store as a global variable
It would store it as a temporary variable, e.g temp1. You can copy the value to the clipboard with the copy(temp1) command in the console, and paste it to your test. It is especially useful when the arguments are objects with many fields or arrays with multiple elements.

Conclusion
Using built-in browser/language features in our code should not stop us writing unit/feature tests for the application to ensure we produce clean code and high-quality software!

Tags: javascript · testing · tips · tricks

Want products news and updates?

Sign up for our newsletter to stay up to date.

We care about the protection of your data. Read our Privacy Policy.

Impressions from our Team

  • #Office #Garden - #

  • #workhard - #

  • #belgrade #skyline - #

  • #happybirthday Phil :) - #

  • #happybirthday Stefan 🥂 - #

  • #happybirthday Lidija 🍾 - #

  • Say hi 👋 to our newest team member ☕️ - #

  • #bithday #cake 😻 - #

  • #stayathome #homeoffice #42coders - #

  • #stayathome #homeoffice #42coders #starwars :) - #

  • #stayathome #homeoffice #42coders - #

  • We had a really nice time with #laracononline #laravel - #

  • Happy Birthday 🎂 Miloš - #

  • Happy Birthday 🎂Nikola - #

  • #42coders #christmas #dinner what a nice evening :) - #

  • Happy Birthday 🎂 Ognjen - #

  • Wish you all a merry Christmas 🎄🎁 - #

  • #happybirthday Luka! - #

  • https://communian.com Triff dich mit Menschen aus deiner Umgebung die deine Interessen teilen :) Wir sind gerade live gegangen und freuen uns über jede neue Community die zu uns kommt ❤️ - #

  • Nice #meetup at #myposter thanks! - #

© 2020 42coders All rights reserved.