views:

253

answers:

2

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?

A: 

In an object oriented language, you would typically unit test the protected methods by having the test class inherit from the class it's testing.

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

I think you either need to make your methods public, or give up on unit testing them.

Chase Seibert
In C#, a derived clas cannot access private members of its base class. Is that different with other languages?
John Saunders
In Java also, a private member or method cannot be accessed by subclasses.
Stephen P
Sorry, I meant protected.
Chase Seibert
Just being pedantic - JavaScript is really object-oriented, but it is not class-based - it is prototype-based.
Neall
+3  A: 

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.

Helgi