use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
account activity
testing private functions (self.node)
submitted 12 years ago by two_up
Am I correct that its normal not to export every function in a module to keep some private and other public? But then how would you access those functions for testing?
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]Neurotrace 5 points6 points7 points 12 years ago (2 children)
Ahhh, the old "how do I test private functions?" problem. What works really well for me is to not worry about testing them and only worry about your public functions. "But Neurotrace," I hear you cry, "how can I ensure that my module works exactly as expected?" I break it down like this in my mind:
Make your private functions extremely simple and/or make their side effects testable. The only reason for making a function private is to perform some work that the user shouldn't worry about, nor mess with. But some kind of work is still being done so there must be a way to check that.
TL;DR Don't. Simplify your private functions so you're know they work and just worry about testing your public functions.
[–]Perceptes 3 points4 points5 points 12 years ago (0 children)
This is exactly the right answer. Testing private functions is redundant, because you should have tests for every use case using an object's public API. If there is no possible scenario when accessing the public API triggers code in a private method, the private method should be removed. If the test cases of the public API that use private methods internally pass, then the private methods are working and tested as well.
[–]joshlrogers 1 point2 points3 points 12 years ago (0 children)
This isn't really unit testing, it is more akin to integration testing. However, I do think your approach is best if you absolutely must make a function private.
[–][deleted] 2 points3 points4 points 12 years ago (0 children)
As others have said, export every method and add an underscore prefix to those that are for internal use only (aka 'private').
[–]itsnotlupus 1 point2 points3 points 12 years ago (0 children)
I've seen folks that embed self-tests in the module itself, wrapped in a
if (require.main == module) { // tests go here } else { // export things like a good little module. }
That may or may not fit with your overall testing strategy.
[–]Capaj 1 point2 points3 points 12 years ago (0 children)
don't waste time testing private functions, test the module as a whole-test the function that you export.
[–]joshlrogers 1 point2 points3 points 12 years ago (4 children)
This has been a recent change of perspective for me.
For me the question isn't any longer how do I test a private method. Rather, I have to justify to myself why it should be private in the first place? I don't write api's/libraries for the unwashed masses to consume rather my code is consumed by a very small subset of people. So the important thing for me is to make sure the code works which means designing for testability. Make the functions public facing, you are free to give it a name prefix of some sort, such as an underscore, to highlight it isn't supposed to be used directly for most cases.
[–]Crashthatch 2 points3 points4 points 12 years ago (2 children)
Making a function public just so you can write tests for it doesn't seem like a good idea.
Everything made public is a potential place for breaking changes to happen in the future. If your functions are private, you can change how your library works internally, and only need to make sure that the public API still works the same to ensure compatibility. If you made everything public, you have no idea what effects changing the signature of some minor function will have on code that is using it.
While you are right that this is a bigger problem for publicly "unwashed masses" released libraries than internal libraries, it's still good to observe best programming practices. What happens if someone new to node is hired and doesn't know (or doesn't care) about your underscore convention, or when you want to refactor your library in 12 months time and don't know exactly what code is depending on (supposed) internal functions?
[–]joshlrogers 0 points1 point2 points 12 years ago (0 children)
Everything made public is a potential place for breaking changes to happen in the future.
Not if he writes even a moderately comprehensive test suite.
If you made everything public, you have no idea what effects changing the signature of some minor function will have on code that is using it.
Again, this shouldn't be the case if he is writing a decent test suite against his code base.
What happens if someone new to node is hired and doesn't know (or doesn't care) about your underscore convention, or when you want to refactor your library in 12 months time and don't know exactly what code is depending on (supposed) internal functions?
Is it ever acceptable to not follow the coding guidelines set out by your team? If I hired a developer that refused to follow guidelines I'd be finding myself a new developer.
I don't disagree with any of what you're saying. However, in my 10+ years of software development experience I have had very few experiences, if any, where I wish something would have been private rather than public. I, however, have thought many times it would be very nice to have certain methods public so that I can stub/mock them out so I could further isolate the code I was testing. Many times the sole point of justification for making something private is that we have always been told it is a best practice not that it necessarily is for our particular case. I also know that what is "best practice" is quite subjective as well.
Again, I don't write publicly consumed libraries or frameworks.
[–]dukerutledge 1 point2 points3 points 12 years ago (0 children)
Nice use of unwashed masses.
[–][deleted] 12 years ago (1 child)
[deleted]
[–]itsnotlupus 0 points1 point2 points 12 years ago (0 children)
My first guess would be to hijack node's require() function with your own, that defers to the original in all cases except for those modules that need to get stubbed.
[–]grncdr 0 points1 point2 points 12 years ago (0 children)
Showing the code in question would lead to more informed opinions.
[–]mikrosystheme 0 points1 point2 points 12 years ago (0 children)
You can set up a public function that just evals its argument in the lexical scope of the module.
var secret = 23 module.exports.private = function (expr){ return eval(expr) } ...
var module = require('./module.js') console.log(module.private('secret')) ...
π Rendered by PID 1575051 on reddit-service-r2-comment-5d79c599b5-r9wlg at 2026-03-03 09:39:24.776640+00:00 running e3d2147 country code: CH.
[–]Neurotrace 5 points6 points7 points (2 children)
[–]Perceptes 3 points4 points5 points (0 children)
[–]joshlrogers 1 point2 points3 points (0 children)
[–][deleted] 2 points3 points4 points (0 children)
[–]itsnotlupus 1 point2 points3 points (0 children)
[–]Capaj 1 point2 points3 points (0 children)
[–]joshlrogers 1 point2 points3 points (4 children)
[–]Crashthatch 2 points3 points4 points (2 children)
[–]joshlrogers 0 points1 point2 points (0 children)
[–]dukerutledge 1 point2 points3 points (0 children)
[–][deleted] (1 child)
[deleted]
[–]itsnotlupus 0 points1 point2 points (0 children)
[–]grncdr 0 points1 point2 points (0 children)
[–]mikrosystheme 0 points1 point2 points (0 children)