I'm using the module pattern in Javascript to separate my public interface from the private implementation. To simplify what I'm doing, my code generates a chart. The chart consists of multiple parts (axises, labels, plot, legend, etc.) My code looks like:
var Graph = function() {
var private_data;
function draw_legend() { ... }
function draw_plot() { ... }
function helper_func() { ... }
...
return {
add_data: function(data) {
private_data = data;
},
draw: function() {
draw_legend()
draw_plot()
}
}
}
Some people advocate only testing the public interface of your classes, which makes sense, but I'd really like to get in some tests to test each of the components separately. If I screw up my draw_legend() function, I'd like that test to fail, not a test for the public draw() function. Am I on the wrong track here?
I could separate each of the components in different classes, for example make a Legend class. But it seems silly to create a class for what's sometimes just 5-10 lines of code, and it would be uglier because I'd need to pass in a bunch of private state. And I wouldn't be able to test my helper functions. Should I do this anyway? Should I suck it up and only test the public draw()? Or is there some other solution?
The short answer is that you shouldn't test private methods directly, but only their effects on the public methods that call them. Unit tests are clients of the object under test, much like the other classes in the code that are dependent on the object.
JavaScript allows you to define private methods for instance methods, static methods, and getter/setters. The following shows the syntax of defining a private instance method: class MyClass { #privateMethod() { //... } }
To test private functions in unit tests with Mocha and Node. js, we can use the rewire module. const rewire = require("rewire"); const foobar = rewire("./foobar"); describe("private_foobar1", () => { const privateFoobar1 = foobar.
Strictly speaking, you should not be writing unit tests that directly test private methods. What you should be testing is the public contract that the class has with other objects; you should never directly test an object's internals.
There is no way to access inner functions (private) from an outer scope. If you want to test inner functions you might consider adding a public method for testing purposes only. If you are using some sort of a build environment, for example ant, you may pre-process the javascript file for production and remove those test functions.
Actually Javascript is an Object oriented language. It's just not a statitcally typed one.
My solution is just a little bit of hack. QUnit example:
At the top of Qunit test html I have declared:
var TEST_AVAILABLE = true;
In the testable class I have a fragment like this:
if(TEST_AVAILABLE){
this.test={
hasDraft:hasDraft,
isInterpIdIn:isInterpIdIn,
// other private methods
};
}
In the QUnit you could verify
test( "hello booth", function() {
var b = new Booth();
ok(b);
ok(b.test);
ok(!b.test.hasDraft());
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With