>
> The problem we've struck is that the private helper functions within each
> module can't be accessed from outside the closure for unit testing. We could
> of course rely solely on our end-to-end tests to ensure correct behaviour,
> but we're striving for more comprehensive coverage than that. Alternatively
> we could expose all of these helper methods so that they can be properly
> tested, however that defeats one of the primary benefits the pattern, namely
> encapsulation. I'm loathe to do sacrifice one benefit for the other, and
> ideally want both.
>

I tend to think about it this way: if the "private" helpers needs testing on
their own, then they probably aren't that private after all. This problem
usually goes away when you write tests first. When I TDD my code, I only
ever introduce new private "helpers" as an act of refactoring. In this case,
all the paths through the private methods currently being used will be
tested.

Tests should describe the observable behavior of your system, and private
methods/state is not part of that behavior. Usually they are implementation
details, sometimes they are generally useful utilities unfortunately trapped
inside a closure.

Retrofitting tests to an existing code base if often much harder than
testing new code. One reason for that may be overuse of closures/private
"helpers". I feel that private methods are generally used way too much, and
often to hide more than implementation specifics. If you have entire
concepts that are hard to describe in tests in terms of your public API,
you've probably hidden too much. If you cannot easily describe some behavior
in a unit test, chances are you cannot easily use it on its own either. This
is usually easier to discover when developing API's for other programmers
than if you're doing applications.

On a general basis my best advice is to consider each private method
carefully - is this really private implementation specifics, or could you
extract some kind of utility/new public methods from it? Extract meaningful
code so it can be tested more easily, and test the rest through the existing
public API.


>
> The only other alternative I can think of is to modify the files at build
> time, perhaps exposing the private methods via a temporary test API object
> or by removing the outer containing function which constrains their scope.
> Of course, that would mean that we'd then be releasing a version of our code
> different from the one we'd tested ... which sort of defeats the purpose.
>

I would advice you not to do that. Keeping the test environment as close to
the production environment is key to build trustworthy tests. Tests that can
not be fully trusted are worthless and will waste your time.

IMHO, exposing methods/state solely for the sake of tests is a code smell,
and to me indicates possible failures in API design. You may also be able to
solve some problems using mocks/stubs in your tests.


> Any thoughts or experiences you have to share would be greatly appreciated.
> I'm a relative novice at TDD, so don't hesitate to mention anything you
> think seems obvious. Likewise, I'm only a third of the way through Christain
> Johansen's excellent book ... so feel free to tell me to at least finish
> that before asking such things, if appropriate ;-)
>

Thanks for the kind words :)

>
Christian

-- 
To view archived discussions from the original JSMentors Mailman list: 
http://www.mail-archive.com/[email protected]/

To search via a non-Google archive, visit here: 
http://www.mail-archive.com/[email protected]/

To unsubscribe from this group, send email to
[email protected]

Reply via email to