But, isn’t the point of unit testing to allow us to test UNITs? Why artificially limit our ability to test units if we don’t need to? If we had the ability to create protected members, wouldn’t we tests those separately?
Creating Private Members
Notice that the only thing that actually makes our publicMember public is that I’ve attached the function pointer to this.
Exposing Private for Jasmine
The easiest way I know of to expose the private member variables for Jasmine is to conditionally assign the private members to this if jasmine is defined.
As long as you don’t use the jasmine global variable for something other than jasmine, this should work.
And now you can test your private functions.
What about Spys?
If you are testing your private functions on their own, you’ll probably have a need to place spys on them when you test the other functions in your application that call them. This is where things get just a bit interesting.
If we leave things as they are, and you place a spy on the function that we exposed, your spy will never get called. The reason for this is because of the way pointers work.
In our example above, our publicMember() function is going to call our privateMember() function regardless of how we manipulate the this.privateMember pointer. This is because, while the variables are pointing to the same function, they are still two different variables and, because of the way spys work internally, you’ll end up changing the this.privateMember variable without impacting the call to privateMember().
We need to write a little extra code in our if(jasmine) block to make sure that after we’ve exposed privateMember(), the now public version of privateMember() gets call by publicMember() instead of the private version of privateMember().
To do this we are going to need to play “towers of hanoi” with our variables.
The gist of what this new code does is that it captures the pointer to the privateMember() into oldPrivateMember. Once we have that, we can make this.privateMember point to the original privateMember and then make our original privateMember point to a new method that calls this.privateMember, which is what our spy will call if we’ve set one up.
The if(oldPrivateMember) stuff is just protection code to make sure we don’t do this more times than we need and end up calling this.privateMember up the call stack multiple times until we finally get to the privateMember function we ultimately want to call. Depending on how you implement classes, you may or may not need this code.
- WebForms vs MVC–The War Is Over - September 25th, 2014
- Create A Desktop Application using Angular, Bootstrap and C# - October 15th, 2015
- Are You Doing Angular Right? - November 5th, 2015
- Adventures Working With Angular’s $scope - November 26th, 2015
- Using Gulp to Bundle, Minify, and Cache-bust - January 28th, 2016
- Reactions to React JS and Associated Bits - March 17th, 2016
- An Explanation of the Flux Pattern - March 31st, 2016
- Ext JS 6 by Sencha - The Good, The Bad, The Ugly - April 7th, 2016
- Do This To Increase Your Client Side Web Development Speed - April 21st, 2016
- ES2015 Code Coverage and Jest (React JS Unit Testing) - May 5th, 2016
- 4 Reasons To Drop MVVM - July 27th, 2016
- You Can Start Using Node Today - August 2nd, 2016
- TypeScript and Electron The Right Way - September 6th, 2016