Design, Build and Release

Ramblings of IainJMitchell on C#, Javascript and Software Craftsmanship

Exposing Javascript private functions for unit testing

2 comments

As in most languages it is good practice to hide internal ‘helper’ functions and not expose them outside. With Javascript closures this is straightforward to do as we simply don’t expose the functions in the API that we return.

For example, in the class below we only return the load() method in the API, so the other method prepareData() cannot be seen outside the closure.

function MyClass(){
	return createApi();	

	function createApi(){
		return {
			load : load
		}
	}
	
	/*
	 * PUBLIC FUNCTIONS
	 */
	function load(url, method, dataArray, successCallback, errorCallback){
		var data = WcfDataLoader.prepareData(dataArray);	
		/* Rest of method ommitted */
	}
	
	/*
	 * PRIVATE FUNCTIONS
	 */
	function prepareData(dataArray){
		/* Method omitted */
	}
}

The only problem with this is that we probably want to unit test the prepareData() method at some point. We could just do this by calling the load() method – as this calls our private method. Different arguments could be passed to this to try and cover all the paths through the prepareData() method.

However, this is not the best way of unit testing a method and we should be trying to test each method in isolation… which means that we need to be able to see our private methods whilst unit testing!

The solution I have for this problem is to change the closure class to have a switch to tell it whether the private methods should be exposed. The code below demonstrates how this would be applied to our example class.

function MyClass(exposePrivateFunctions){
	return createApi();	

	function createApi(){
		var privateFunctions = createPrivateApi();
		return {
			load : load,
			privateFunctions : privateFunctions							
		}
	}
	
	function createPrivateApi(){
		if (exposePrivateFunctions) {
			return {
				prepareData: prepareData
			}
		}				
	}
	
	/*
	 * PUBLIC FUNCTIONS
	 */
	function load(url, method, dataArray, successCallback, errorCallback){
		var data = WcfDataLoader.prepareData(dataArray);	
		/* Rest of method ommitted */
	}
	
	/*
	 * PRIVATE FUNCTIONS
	 */
	function prepareData(dataArray){
		/* Method omitted */
	}
}

We then can create this class in two seperate ways, the ‘normalVersion’ that does not expose the private methods and the ‘testVersion’ that does expose them.

var normalVersion = new MyClass();
var testVersion = new MyClass(true);

Written by IainJMitchell

April 13th, 2010 at 1:42 pm

Posted in Uncategorized

Tagged with ,

2 Responses to 'Exposing Javascript private functions for unit testing'

Subscribe to comments with RSS or TrackBack to 'Exposing Javascript private functions for unit testing'.

  1. I like the idea of ths approach. Perhaps consider looping through the class type to get all functions to return, so as you add functions, you don’t have to update your initializer / accessor.

    Mark Booth

    23 Dec 10 at 6:08 pm

  2. Excelent strategy. Then on your backend you could just set some kind of flag in your framework to trigger exposing privates.

    If testMode
    MYFRAMEWORK.testMode = true

    Thanks for sharing!

    dan

    19 May 12 at 8:06 pm

Leave a Reply