1
votes

The consensus seems to be not to test private methods when doing TDD.

Should Private/Protected methods be under unit test?

I keep hitting this same scenario. I have a private method (as an example it switches all options to off). It changes lots of state and is called by a few public methods. The changes that the private method makes to the state will remain the same regardless of which public methods get called (all options get set to off).

What's the best way to test the functionality of this private method without adding many tests that effectively do the same thing?

btw, I'm using QUnit to test Javascript objects.

Here is an overly simplified version of my class.

http://jsfiddle.net/twistedinferno/UMgAx/

Edit

What I'm really trying ask here is not 'should I or shouldnt I test private methods' as that has already been answered and the answer to that is no. I want to know how do I best test each public method bearing in mind that many of the assertions will be the same due to the use of my private method. The same private method gets called by many public methods. Is it ok to have a lot of duplicate assertions to test the change of state that occurs when each one of many public methods call my private method?

new fiddle with tests http://jsfiddle.net/twistedinferno/JHzWh/

3

3 Answers

4
votes

Test the public methods.

Or, more generally, test the outwardly-visible interface for the object.

If the private method is used by the public methods, its use will be tested as a result. But the private method itself, being private, isn't a concern for anything outside of that object, including the tests.

These tests shouldn't know or care that such a private method even exists, let alone whether or not they're testing it. They should test all public functionality.

If the many tests are doing the same thing, might that be an indication that there's unnecessary overlap in the public functionality? Maybe there's room for re-factoring there? It's entirely conjecture without seeing any code, of course. Can you provide an example?

Edit

The additional assertions duplicate the same keystrokes, but the tests are distinctly different because they're testing different outward-facing functionality. You can always refactor out the duplicated assertions into a single function that each test calls. Sort of a custom aggregate assertion. As long as the public methods continue to have the same observable (and testable) behavior then that's fine. As soon as one changes, its test will need to change as well of course.

2
votes

Given that you are practicing TDD, I would presume that each line of code in the private method in question would not have existed in the absence of a test that required it being written. That implies that there is no need to test the private function independently of the public interface.

Thanks!

Brandon

1
votes

I agree with bcariso and David. You shouldn't test, nor should you have to test, private methods.

One thing to note, is that if your private method is so big and important, that you feel you must test it, you should consider extracting it to be a public method of its own helper-class.

In Javascript, the same principle stands, only that you'd make it a publicly visible function, or a module (if you use that pattern).