JavaScript is difficult to test?

Well that is what I thought, until someone introduced me to Jasmine, no not Aladdin’s girlfriend, the Jasmine Testing Framework.

jasmine

Intro

Firstly, I’m no JavaScript guru, my knowledge level is VERY basic. I do work with JavaScript and jQuery, but previously have not really tried to write tests for it. Instead I have usually copied code from an example I found online; poked at it until it did what I wanted and then never looked at it again. But not this time.

Our company is relatively new to agile processes (2 years’ish) and we are doing great with BDD on the Ruby side of things, but we currently don’t have any tests for our JavaScript. So as some JavaScript work needed doing we decided to try to write some tests using jasmine.

In this post I won’t cover setting up jasmine, there are a number of tutorials around that do this. I used this and this which showed me how to set up a standalone version which comes with a few tests. I won’t cover how jQuery’s autocomplete works as this is covered on their site.

Instead I want to talk about what I needed to test and how I had to change our code to make it testable.

sb-tech-site-technology

The Problem

We have a trade selector that uses jQuery’s autocomplete. This takes an array of objects to supply the data for the autocomplete dropdown as well as a parameter used when we redirect after a trade is selected.

I was given a task of updating this so that the redirect was conditional based on the trade selected. e.g. the Accountant should still redirect to some.site.for.business, but a Baker should redirect to some.site.for.shop. But I wanted to do this test driven.

My first problem was I had no way to cleanly hook into the code and with my lack of understanding of how JavaScript events and inline functions worked the task seemed immense. So I started chipping.

My thought was that I don’t need to test ‘autocomplete’ as that is ‘hopefully’ tested by the makers of jQuery. I also didn’t need to test that the correct item was being passed to the ‘result’ function as that was working already. What I really wanted to test was the function that was being called from the ‘results’ function. So my first change wasn’t exactly TDD but it opened a crack to let me in:

This allowed me to write my first test in my AutocompleteSpec.js file:

Great I had a test and it passed. Right? Wrong! As I was trying to make expectations on location.href (not a function) Jasmine was not able to check expectations and each time I called the test my Jasmine SpecRunner.html would change location to my redirected page. Doh! So my second change was to add another function:

Again, it does mean that all I’m doing is wrapping up functionality into discreet functions but it did allow me to change my tests like so:

Now I had a valid test and could get on with writing some failing tests. So here is my first:

So now I could finally get on and implement my new redirect code:

And both my tests pass.

Now I am only showing you a part of the real code and a fraction of the full trade list and there was still a whole load of refactoring to be done but by the time I had finished I had over 800 specs surrounding this code, but I think this illustrates the point.

Jasmine made writing the tests easy and very RSpec like, but your code (even JavaScript) needs to be written for testability. Wrapping up your JavaScript into small discreet functions instead of a large inline set of functions, makes it a lot easier to test your code in isolation.

I used to think JavaScript is difficult to test? Not any more 🙂

Ready to start your career at Simply Business?

Want to know more about what it’s like to work in tech at Simply Business? Read about our approach to tech, then check out our current vacancies.

Christopher Chamberlain

This block is configured using JavaScript. A preview is not available in the editor.