top of page
Writer's pictureselinov

JS Tests in Jasmine

Test driven development has been a welcome standard and a pain for a few of the team projects that I’ve been on. Since I tend to live on the client side I haven’t had to worry much about writing tests. Well, that’s over because the age of javascript applications is here.

Jasmine makes it super easy to test individual methods in your Javascript code. Let’s take a look at a simple code snippet.

currentFlo = 0;
currentTime = new Date().getTime();

Flos = {
    
    helloWorld : function(){
        return ("Hello world!");
    },
    detectFlo : function(time,startDate,cycle){
        var myTime = new Date(time).getTime();
        var myDate = new Date(startDate).getTime();
        var status = ( secToDays(myTime) - secToDays(myDate) ) % (cycle);
        return status;
    }
}

Lines 1-2 declare a couple of globals that we’ll use throughout the app. They contain no security risks or personal data.

Lines 4-7 create a basic “Hello world” response. I use this as a case positive to make sure that the framework is working at all. When this method stops working then something is definitely wrong. It serves no other purpose and likely will be ripped out on a production build.

Lines 9-14 makes the only real method in this example. It creates two variables with date strings that have been passed into it. Takes those two dates, converts them an actual number of days using a helper method, then runs some simple math on them. It returns an integer.

Ok, let’s examine the tests for these. Lines 1-5 will test the “Hello world!” method. I try to always put this test first since it’s really testing the framework. It’s made up of three distinct parts; describe(), it(), and expect(). The describe() function passes a simple text string to the test suite just so you have something human readable to describe the test. There’s no relation between the value and the actual method being tested. The it() function also passes a simple text string in the case of passing. Again, there’s no real relation other than the one in your mind as the coder. It should make sense to you and to anyone looking at the tests as to what this thing is supposed to be doing. Lastly, the expect() function is actually doing something.

It takes the real name of the method being tested and runs whatever comparison you desire against the result passed back by that method. The the case of Flos.helloWorld we’ll need to see if the string passed back is equal to “Hello world!”.

describe("Hello world", function() {
         it("says hello", function() {
            expect(Flos.helloWorld()).toEqual("Hello world!");
            });
         });

Now that we have a basic understanding and expectation of the framework we can start doing some actual tests. This nest snippet tests to see if those globals that we require through the app’s lifecycle have been instantiated. Do they exist at all?

We expect() them toBeDefined(). In the case of the currentFlo var we also expect it toEqual an integer value of zero. If I wanted to be really fancy I could also see if currentTime is within a certain number of milliseconds of ‘new Date()’ but let’s not go there.

describe("Checks if global currentFlo and currentTime exist", function() {
         it("currentFlo = 0 & currentTime exist", function() {
            expect(currentFlo).toBeDefined();
            expect(currentFlo).toEqual(0);
            
            var myTime = new Date().getTime();
            expect(currentTime).toBeDefined();
            });
         });

As you can see, these are just functions! Easy peasy, right? That means we can do pretty much anything we’d do in a custom method; declare variables, return methods as values, etc. The last snippet makes three primitives  and passes them to the detectFlo() method and then expects a value of zero to be returned. I try to use primitives because they are static over time. I know that these values worked when I wrote the test and they should always return zero no matter what the date is.

describe("Detect Flo", function() {
         it("returns 0", function() {
            var time = 1388135645554;
            var startDate = "2013-12-27";
            var cycle = 30;
            expect(Flos.detectFlo(time,startDate,cycle)).toEqual(0);
            });
         });

When this is all done and ready to test you can just load the test suite into any JS browser. When all the tests pass you get something like this. It’s remarkably fast, simple, and reliable.

Comments


bottom of page