I am using mocha in order to unit test an application written for node.js
I wonder if it's possible to unit test functions that have not been exported in a module.
Example:
I have a lot of functions defined like this in foobar.js
function private_foobar1(){
...
}
function private_foobar2(){
...
}
and a few functions exported as public:
exports.public_foobar3 = function(){
...
}
The test case is structured as follows:
describe("private_foobar1", function() {
it("should do stuff", function(done) {
var stuff = foobar.private_foobar1(filter);
should(stuff).be.ok;
should(stuff).....
Obviously this does not work, since private_foobar1
is not exported.
What is the correct way to unit-test private methods? Does mocha have some built-in methods for doing that?
I made an npm package for this purpose that you might find useful: require-from
Basically you expose non-public methods by:
note:
testExports
can be any valid name you want, exceptexports
of course.And from another module:
I followed @barwin answer and checked how unit tests can be made with rewire module. I can confirm that this solution simply works.
The module should be required in two parts - public one and private one. For public functions you can do that in standard way:
For private scope:
In order to know more about the subject, I created a working example with full module testing, testing includes private and public scope.
For further information I encourage you to check the article (https://medium.com/@macsikora/how-to-test-private-functions-of-es6-module-fb8c1345b25f) fully describing the subject, it includes code samples.
Check out the rewire module. It allows you to get (and manipulate) private variables and functions within a module.
So in your case the usage would be something like:
If you'd prefer to keep it simple, just export the private members as well, but clearly separated from the public API with some convention, e.g. prefix them with an
_
or nest them under a single private object.Here is a really good workflow to test your private methods explained by Philip Walton, a Google engineer on its blog.
Principle
_
for exampleThen use a build task or your own build system (for exemple grunt-strip-code) to strip this bloc for production builds.
Your tests builds have access to your private api, and your production builds have not.
Snippet
Write your code as this:
And your grunt tasks like that
More deeper
In a later article, it explains the "why" of "testing private methods"
If the function is not exported by the module, it cannot be called by test code outside the module. That's due to how JavaScript works, and Mocha cannot by itself circumvent this.
In the few instances where I determined that testing a private function is the right thing to do, what I've done is set some environment variable that my module checks to determine whether it is running in a test setup or not. If it runs in the test setup, then it exports additional functions that I can then call during testing.
The word "environment" is loosely used here. It might mean checking
process.env
or something else that can communicate to the module "you're being tested now". The instances where I've had to do this were in a RequireJS environment, and I've usedmodule.config
for this purpose.