Testing private functions in javascript

I use the module template in Javascript to separate my public interface from a private implementation. To simplify what I'm doing, my code generates a diagram. The diagram consists of several parts (axis, labels, plot, legend, etc.). My code looks like this:

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 testing only the public interface of your classes, which makes sense, but I would really like to pass some tests to test each component individually. If I messed up my draw_legend () function, I would like this 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, create a Legend class. But it seems foolish to create a class for what sometimes is only 5-10 lines of code, and that would be terrible, because I would need to pass a bunch of private state. And I could not test my helper functions. Should I do this? Should I suck it and check only the public ()? Or is there another solution?

+16
javascript unit-testing
Apr 04 '09 at 0:53
source share
6 answers

There is no access to internal functions (private) from the external area. If you want to test internal functions, you might consider adding a public method for testing purposes only. If you are using any build environment such as ant, you can pre-process the javascript file for production and remove these test functions.

In fact, Javascript is an object oriented language. It is simply not typically printed.

+9
Apr 05 '09 at 19:42
source share

My solution is just a little hack. QUnit example:

At the top of the Qunit html test, I stated:

 var TEST_AVAILABLE = true; 

In the tested class, I have this fragment:

 if(TEST_AVAILABLE){ this.test={ hasDraft:hasDraft, isInterpIdIn:isInterpIdIn, // other private methods }; } 

In QUnit you can check

 test( "hello booth", function() { var b = new Booth(); ok(b); ok(b.test); ok(!b.test.hasDraft()); }); 
+5
Jan 29 '13 at 8:44
source share

I have a similar problem. The solution I came up with is not what I like, but it does the job, and there is no better solution that I can find.

 function Graph() { this.Test = function _Test(expressionStr) { return eval(expressionStr); } var private_data; function draw_legend() { ... } function draw_plot() { ... } function helper_func() { ... } ... } 

To check:

 var g = new Graph(); g.Test("helper_func()") == something; g.Test("private_data") == something2 
+3
Oct 08
source share

Actually there is an easy way. You can use ajax to load the script and insert a function that provides private functions. I have an example here that uses qUnit and jQuery. But I'm sure the same can be easily done using pure Javascript.

+1
Aug 24 '12 at 15:35
source share

In an object-oriented language, usually unit test methods are protected if the class of the class inherits from the class being tested.

Of course, Javascript is not really an object-oriented language, and this template does not allow inheritance.

It seems to me that you need to either publish your methods or refuse to test modules.

0
Apr 04 '09 at 1:05
source share

There is only one correct option: Various assemblies for testing and production

1) mark only parts of development

 /* test-code */ api._foo = foo /* end-test-code */ 

2) separate them later ...;)

 grunt.registerTask("deploy", [ "concat", "strip-code", ... 

@philwalton wrote beautiful articles:

0
Dec 06 '16 at 16:13
source share



All Articles