开发者

Unit testing private methods in functional inheritance

开发者 https://www.devze.com 2023-03-18 03:20 出处:网络
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

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(strin开发者_Python百科g) {
            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?


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?


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


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"

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号