undefined

Javascript scope mechanics don’t allow you to access the private functions of a class/function which makes it pretty hard to unit test. Your alternatives usually are either to create a unit test function inside your code to expose your other private functions or change your code style to expose all functions all the time (please let me know if there are more options.

I’ve come up with one more solution. By injecting code into the class string, we can create a method that returns all private functions and exposes them for what ever unit test needs you might have. The code creates an instance of the class and doesn’t modify your original code.

Lets pretend you have this overcomplicated function/class:

var Foo = function() {
    function add(a,b) {
        return a + b;
    }
}

When we create an instance of it: var boo = new MyClass(); we can’t access boo.add because it’s private so we cant test it.

But if with a little help of a small function I wrote, we create an instance like this:

var fooExposed = getExposedInstance(Foo);

We get an instance of boo with a property called _privates that exposes all internal functions. In this case, we can access add() like this:

var fooExposed = getExposedInstance(Foo);
fooExposed._privates.add(1, 2);

And we can easely test them:

var fooExposed = getExposedInstance(Foo);
var result = fooExposed._privates.add(1,2); 
Assert.Equals(result, 3);

Here is the code for getExposedInstance:

function getExposedInstance(classRef) {
    // get the functions as a string
    var classAsString = classRef.toString();

    // To expose the private functions, we create
    // a new function that goes trough the functions string
    // we could have done all string parsing in this class and
    // only associate the functions directly with string
    // manipulation here and not inside the new class,
    // but then we would have to expose the functions as string
    // in the code, which could lead to problems in the eval since
    // string might have semicolons, line breaks etc.
    var funcString = "";
    funcString += "new (";
    funcString += classAsString.substring(0, classAsString.length - 1);
    funcString += ";";
    funcString += "this._privates = {};n";
    funcString += "this._initPrivates = function(f)";
    funcString += "{";
    funcString += "var fs = f.toString();";
    funcString += "var pf = fs.match(/functions*?(w.*?)(/g);";
    funcString += "this._privates = {};";
    funcString += "for (var i = 0, ii = pf.length; i < ii; i++)";
    funcString += "{";
    funcString += "var fn = pf[i].replace(/(functions+)/, '').replace('(', '');";
    funcString += "this._privates[fn] = eval(fn);";
    funcString += "}";
    funcString += "}";
    funcString += "nn})()";

    var instance = eval(funcString);
    instance._initPrivates(classAsString);

    // delete the initiation functions
    delete instance._initPrivates;

    return instance;
}

So, with a little javascript eval, you can expose your private functions for testing.