Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write unit test on code that is using Google Maps for JS

I'm writing some JavaScript module that is meant to running in browser (client side, not server side). This module is using Google Maps JavaScript API.

I want to cover my code by unit tests. I also want my tests to be isolated. I found several vcr-like JS libraries for recording and mocking HTTP-requests that Google Maps Api is producing. But all of them are for Node.JS (because PhantomJS doesn't support using fs module). Also Node.JS has more rich and readable backtraces than PhantomJS has.

So I'm wondering how to include Google Maps Javascript API to my tests with Node.JS-based test runner and how to write test for my code?

P.S. I'm not stick with some certain JS unit-test library. It can be Jasmine, QUnit or any other.

P.P.S It not necessary should be Node.JS runner. If there are another options it is completely OK!

P.P.P.S. My goal is to avoid following things:

  1. to avoid dependency on internet connection and corresponding delays in tests
  2. to avoid failing tests because of changing some GEO data on Google servers. For example: if I use directions, I don't really care if it 2000 meters or 2001 meters, I just wanna know, that I get some appropriate data from Google and perform some calculations with it.

P.P.P.P.S. Thanks to @MichaelGeary answer we know that Google saves only 3 versions of their API. But I'm not focusing only on Google Maps, I chose it in that question because of it's popularity/ I have the same question applied to any other maps api like Yandex.Maps, Leaflet (with openstreet), Bing and etc. Most of them don't delete old APIs, so I can fix version and rely on not changing internal API and HTTP requests.

Also I want to avoid mock hell, because my code is quite complex and uses a lot of geo objects of different kind. So it will not be easy to mock all of them and then support that code. It looks like unbearable thing.

My idea is to fix version of API for some time (in Google case for not so long time) and rely on persistence of internal HTTP requests format. And from time to time delete all recorded data to be sure that everything is still OK in real world.

I want myself to be one who control when I should fix my test. I don't wanna Google to break my tests at random moment of time.

like image 596
petRUShka Avatar asked Jun 21 '15 10:06

petRUShka


People also ask

Can we write unit test for JavaScript?

JavaScript Unit Testing is a method where JavaScript test code is written for a web page or web application module. It is then combined with HTML as an inline event handler and executed in the browser to test if all functionalities are working as desired. These unit tests are then organized in the test suite.

Does Google Maps use JavaScript?

Like many other Google web applications, Google Maps uses JavaScript extensively.


1 Answers

Recording or mocking the HTTP requests made by the Maps API is certainly an interesting idea!

Unfortunately, like any other undocumented features of the API, these requests are an internal implementation detail and are subject to change at any time. Google rolls out new versions of the API code four times a year, along with patch revisions as frequently as every few weeks. Any of the API internals—including the HTTP requests—could change from one version to the next, even in the patch revisions. The only thing they guarantee to be stable across versions or patches is the documented API.

Google does give you the ability to request a specific API version, but they don't keep old versions around for very long, and they don't keep old patch revisions at all. In fact, only three versions are live at any time. At this writing, these versions are available:

  • The experimental version, currently 3.21.4.
  • The release version, currently 3.20.12.
  • The frozen version, currently 3.19.19.

When the next experimental version (3.22) is rolled out, 3.21 will become the release version, 3.20 the frozen version, and 3.19 will be retired and no longer available.

The frozen version does have one difference from the release and experimental versions: it no longer receives any patches so it is completely stable. It should be safe to assume that the HTTP requests made by the frozen version won't change. But this only helps until that version is retired.

Here is a fiddle to experiment with requesting different API versions and displaying what version is actually loaded. The code looks like this:

<!DOCTYPE html>
<html>
<head>
    <title>Google Maps API version test</title>
</head>

<body>
    <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
    <script src="http://maps.google.com/maps/api/js?v=3.18&sensor=false"></script>

    <div id="version"></div>

    <script>
        $('#version').text(
            'google.maps.version is ' +
            google.maps.version
        );
    </script>

</body>
</html>

The fiddle uses a v=3.18 parameter in the Maps API script URL to request version 3.18, but it actually loads version 3.19.19 at this moment. You can change the v= parameter to different values to see which API version gets loaded. (Besides the specific numbered versions, you can also use v=3 to get the current stable version, or v=3.exp to get the current experimental version.)

The sharp-eyed reader may note that the google.maps.version property this code displays is itself undocumented! But hey, this is experimental test code. :-)

It's fairly common for the HTTP requests to change from version to version, and even possible for them to change in a patch revision. As you can see from the list above, version 3.19 has gone through 19 patch revisions, and 3.20 has gone through 12 patch revisions.

If you want to write unit tests for your Maps API code, my suggestion is to mock the documented Maps API itself instead of mocking any of its internals. For example, your mock for google.maps.Map could check that its first parameter is a DOM node and that its second (optional) object parameter contains only known properties with legitimate values for those properties.

Of course the Maps API exposes quite a large number of objects, methods, and properties, but you don't have to mock the whole thing, just the parts of it you are using.

like image 50
Michael Geary Avatar answered Oct 22 '22 04:10

Michael Geary