Post navigation

Unit testing an AngularJS directive’s private functions.

As we all know Javascript gives us the awesome ability to create functions inside functions. This allows us to create private functions which support the main function. It is also something we do often when creating object functions. This structure is used by angular for the creation of providers and directives alike.

Every once in a while I personally come to a point where I would like to test these private functions. This is especially true for use cases in Angular such as directives.I’d like to be able to run unit tests for a directive’s private functions, but I’d like to do this without having to make them public. The way I do this is by using a concept called reflection. This process actually described by Bob Gravelle in his post ‘Accessing Private functions in Javascript‘ actually exposes the private functions by using the toString method of a function.

Before I go into specifics let me say that this article should only be used as an approach for unit testing. There is a good reason for keeping private functions private and using this concept for application code may very well introduce interesting side effects.

That being said let’s go into details. In order for us to use this concept we’ll need to make some slight changes to our directive. Normally we would declare our Directive Definition Object (DDO) and directly return it. As below:

Declaring and returning our DDO

JavaScript

1

2

3

4

return{

restrict:'E'

...

}

This creates a problem when we try to expose the directive code. As keeping this would end up in an evaluated return statement and the corresponding DDO. So in order to get our private functions we’ll split the declaration and return statements. As below:

Splitting the declaration and return statements.

JavaScript

1

2

3

4

5

6

varinstance={

restrict:'E',

...

}

returninstance;

Now our directive is ready to be read for exposure. In order to expose the directive’s contents we need to create a function that does so. This will be i slightly modified version of Bob Gravelle’s reflection object..

As you can see in the highlighted line (18) i effectively remove the “return instance;” code from the function body. This means that when we evaluate the code we get back the function rather then it’s return object. Thus allowing us to read the private functions.

So when we call the following line we end up wit a variable myInputDirectiveExposed which contains an object _privates containing the private functions. This object can then be used to unit test the individual private functions.

JavaScript

1

2

varmyInputDirectiveExposed=

Reflection.createExposedInstance(myInputDirective);

In order to play around with this system i’ve created a plnkr. Please feel free to play around with it.