4

I just read this great book on Test-Driven Development for Javascript, and in there he mentioned an amazing way of creating objects with private members, originally created by Douglas Crockford, that is called "functional inheritance". It goes like this:

    this.funcInh = function() {
        var privateString = "functional inheritance";

        function setPrivateString(string) {
            privateString = string;
        }

        function getPrivateString() {
            return privateString;
        }

        return {
            setPrivateString: setPrivateString,
            getPrivateString: getPrivateString
        };
    };

While i really love this way of creating objects, I'm wondering how on earth i can test it, other than testing the return value of the privileged functions 'setPrivateString' and 'getPrivateString'. This is just an example, but I can't really see any way to test "private" functions or that the privileged functions call the functions they should... Any ideas?

Robin Heggelund Hansen
  • 4,906
  • 6
  • 37
  • 54

3 Answers3

2

Do you really want to test privates?

I think as far as your public methods are working as expected and providing correct results to "outside world" you should not care what and how it works "inside the box".

See more on this: Should I test private methods or only public ones?

Community
  • 1
  • 1
Laimoncijus
  • 8,615
  • 10
  • 58
  • 81
  • I partly agree with you. In some cases though, a function can give what seems to be a correct return, and the only way to know for certain is the test one of the private functions... I'll assume however, that this is very difficult with functional inheritance... – Robin Heggelund Hansen Jul 06 '11 at 12:57
  • 1
    From my own experience: it is much easier without testing privates - if your public method calls some privates (which does something else - e.g. creates files/does something on DB/orr whatever) - it is easier just to test the result of public method and additionally test either "external" things like files, data on DB, etc are created/modified/deleted/etc as expected - without "knowing" about privates and their implementation - in this way you can always completely change internal things and tests will run fine as far as the public result and all "external" resources/data are the same at end – Laimoncijus Jul 08 '11 at 07:07
0

Organize the private members and functions into an another class, that can you test. Or create a public test function, that works just in the test environment, otherwise throws an exception

Aaaaaaaa
  • 2,015
  • 3
  • 22
  • 40
0

Here is a really good workflow to test your private methods explained by Philip Walton, a Google engineer on its blog.

Principle

  • Write your code normally
  • Bind your private methods to the object in a separate code bloc, mark its by an _ for example
  • Surround that code bloc by start and end comments

Then 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:

var myModule = (function() {

  function foo() {
    // private function `foo` inside closure
    return "foo"
  }

  var api = {
    bar: function() {
      // public function `bar` returned from closure
      return "bar"
    }
  }

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

  return api
}())

And your grunt tasks like that

grunt.registerTask("test", [
  "concat",
  "jshint",
  "jasmine"
])
grunt.registerTask("deploy", [
  "concat",
  "strip-code",
  "jshint",
  "uglify"
])

More deeper

In a later article, it explains the "why" of "testing privates methods"

Rémi Becheras
  • 14,902
  • 14
  • 51
  • 81