Testing private functionality in JavaScript
9 JUL 2013
Start with this example, modified from http://philipwalton.com/articles/how-to-unit-test-private-functions-in-javascript/ by @philwalton
var myModule = (function() {
function foo() {
// private function `foo` inside closure
return "foo"
}
return {
bar: function() {
// use private foo
foo()
// public function `bar` returned from closure
return "bar"
}
}
}())
Testing function bar is straightforward: the call to myModule() should return the string 'bar' in this case.
But how do we test that the internal function foo behaves correctly, given that it is hidden in a closure?
Take the tests for foo and bar in separate stages:
- Since foo is a dependency for
bar, we need to testfoofirst. - Whether or not
foois to be private, we should testfoofirst as a public api. - If
foois to be private, then it shouldn't do too much. That will keep the tests short. - However, if
foodoes a lot, then it shouldn't be private. - Once you're satisfied with the
footests, hide foo in the closure. - Then ask, how does
barusefoo? justfoo(x)orreturn foo(x)? what gets passed to it? does it get modified? - And once you've answered that, you can let or make
bartestfoofor you. - Since you won't need the
footests anymore, you can move assertions as you need them directly intobaritself and modify as necessary. These would typeof or greater than assertions, or has a property, etc.
The point is, don't get hung up on private anything as something to be mocked. We don't need mocks so much as we good test+dev workflow and ergonomics. That prevents us from overthinking or seeking heroic solutions, and keeps away the anxiety and burnout ~ TDD is meant to do all that.
13 JUL 2013 - done - https://gist.github.com/dfkaye/5988926 - "testing requests that use a private method sequence requires a public way to query status information"