Skip Navigation LinksHome > View Post

Unit testing Mobile Services scripts (Day 7)

Many developers are big fans of unit testing. I’m a big fan of unit testing, especially when authoring algorithms or tight routines with few dependencies. The ROI for that kind of code is huge; in fact, in this situation a unit test is often the easiest and cheapest way to test your code. It’s not that often that I end up writing that kind of code when building Mobile Services (though it does happen) and when I do, I want unit tests.

The first time I did this I simply split my code into multiple functions and created a unit test to execute certain functions. Here’s an example using the Mocha testing framework for JS (id TDD mode)

var assert = require('assert');

// the function I'm testing
function add(a, b) {
    return a + b;
}

// my test suite for the calculator
suite('calculator', function() {
    // a test in my suite
    test('add', function() {
        // the test
        var result = add(1, 2);
        // my assertion
        assert.strictEqual(result, 3);
    })
});

If you’ve done any unit testing before, this should look familiar – the notion of suites containing tests that pass or fail. I can install mocha using npm (see this post to get you started with node and npm).

npm install –g mocha

And then you can run your tests

mocha test.js –-ui tdd

And you’ll get your results:

image

Easy, and all green! My add function could easily be more complicated (insert your prime number or fibonacci code) and this is a great way to get any complicated functions working before I use them in my Mobile Service. One place where unit testing gets weird is async. Javascript async is typically handled using callbacks (especially in node) so let’s imagine if our add method was async:

function add(a, b, callback) {
    setTimeout(function() {
        callback(null, a + b);
    }, 500);
}

Note that I added a delay of 0.5s to make it _really_ async. Now to test this we need to tell Mocha when we’ve done waiting for the async and are happy to declare the test passed. Here’s our code:

suite('calculator', function() {
    test('add', function(done) {
        add(1, 2, function(e, result) {
            assert.strictEqual(result, 3);
            done();
        });
    })
});

Notice how we specify the ‘done’ parameter in the test function. This informs Mocha that this is an async test and it should wait for me to call ‘done()’. Smart eh?

image

Notice how this test took a while longer (just over 500ms). Now that we’re grounded in Mocha and testing functions – what if I wanted to test my actual scripts? You know, the insert and read methods, for example?

In this case, you will have to do a little mocking of the Mobile Service request object (and possibly the user and query objects, depending how complicated you want to go) but it’s pretty simple. Let’s recap the request object:

request.execute() – when called with no parameters means go ahead, I’m done with any changes to the request – get on with it!


request.execute({ success: fn }) – call my success function and don’t send the response to the client, the consumer will do that now


request.respond() – send a response to the client with the canonical HTTP status code and JSON body for this operation

As an example, imagine we have an insert script that encrypts the value of a particular property (text) and a read script that decrypts it – this means this value is encrypted at rest in your SQL database. How could we test that?

And there you have it, some tests that can execute against your Mobile Services scripts allowing you to develop locally and be really sure your stuff works. Combine this with this post and you are getting really deeply serious about your Mobile Service workflow.

This was Day 7 of the twelve days of ZUMO – we’ll be back again tomorrow for Day 8.

 
Josh Post By Josh Twist
11:22 PM
27 Dec 2012

» Next Post: Generating your own ZUMO auth token (Day 8)
« Previous Post: A Mobile Services Log Watcher (Day 6)

Comments are closed for this post.

Posted by Mauro @ 14 Jan 2013 10:46 AM
Hey Josh,

Thanks for the excellent series, I'm kind of new to the whole Node and Mobile Services scene, and I was wondering how would you mock other items, such as the tables object as in this example.

https://github.com/WindowsAzure/azure-mobile-services/blob/master/samples/doto/ServerScripts/devices.insert.js

in particular the following : var devices = tables.getTable('devices');

Thanks very much and thanks again :)

Mauro

© 2005 - 2014 Josh Twist - All Rights Reserved.