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 testfoo
first. - Whether or not
foo
is to be private, we should testfoo
first as a public api. - If
foo
is to be private, then it shouldn't do too much. That will keep the tests short. - However, if
foo
does a lot, then it shouldn't be private. - Once you're satisfied with the
foo
tests, hide foo in the closure. - Then ask, how does
bar
usefoo
? 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
bar
testfoo
for you. - Since you won't need the
foo
tests anymore, you can move assertions as you need them directly intobar
itself 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"