How do you unit test private methods?

  • I am working on a java project. I am new to unit testing. What is the best way to unit test private methods in java classes?

    Check this question on StackOverflow. A couple of techniques are mentioned and discussed. What's the best way of unit testing private methods?

    My opinion has always been that private methods don't need testing as you should be testing what is available. A public method. If you can't break the public method does it really matter what the private methods are doing?

    Both public and private methods should be tested. Hence, a test driver generally needs to be inside the class it tests. like this.

    @Rig -- +1 -- you should be able to invoke all the required behavior of a private method from your public methods -- if you cannot then the functionality can never be invoked anyway so there is no point in testing it.

    Use **`@Jailbreak`** from the Manifold framework to directly access private methods. This way your test code remains **type-safe** and readable. Above all, **no design compromises, no overexposing methods and fields for the sake of tests.**

    Never gets old.

    @Rig: If you _can_ break the public method, it suddenly _really_ matters what the private methods are doing.

  • Adam Lear

    Adam Lear Correct answer

    9 years ago

    You generally don't unit test private methods directly. Since they are private, consider them an implementation detail. Nobody is ever going to call one of them and expect it to work a particular way.

    You should instead test your public interface. If the methods that call your private methods are working as you expect, you then assume by extension that your private methods are working correctly.

    +1 bazillion. And if a private method is never called, don't unit-test it, delete it!

    I disagree. Sometimes a private method is just an implementation detail, but it still is complex enough that it warrants testing, to make sure it works right. The public interface may be offering a too high level of abstraction to write a test which directly targets this particular algorithm. It's not always feasible to factor it out into a separate class, for due to the shared data. In this case I'd say it's OK to test a private method.

    @Steve: "delete it"?!!?

    @Anna Lear: But then couldn't you just stick all the contents and logic of public Thing() into private DoThing(), have Thing() call DoThing() and just unit test the simple Thing()?

    @Hippo: if your class has a private method that is never called, it is dead code and you do not need it. –

    Of course delete it. The only possible reason not to delete a function you aren't using is if you think you may need it in the future, and even then you should delete it but note the function in your commit logs, or at least comment it out so that people know it's extra stuff they can ignore.

    @Hugo Sure, you could. I'm not sure I understand the question. So long as your tests cover the required/expected behaviour of `Thing()` its implementation is irrelevant.

    @quant_dev: Sometimes a class needs to be refactored into _several_ other classes. Your shared data can be pulled into a separate class too. Say, a "context" class. Then your two new classes can refer to the context class for their shared data. This may seem unreasonable, but if your private methods are complex enough to need individual testing, it's a code smell that indicates your object graph needs to become a little more granular.

    @Phil Complex object graphs are also a code smell.

    @jhocking: When you define the API of some library module (especially if it is a general-purpose module), you do not consider the public functions that you **actually** use in your **current** code, but the public functions that one would expect to find in such a library. So you do not keep adding and removing API functions just because you need / do not need them in your current code.

    In retrospect I worded that statement too absolutely; you're right that a general purpose library could be an exception. Although note that we were talking about 'private' methods, not 'public'. If you are writing a library then that probably means there are others using it so you can't be sure a public function isn't being used by someone, whereas you know for sure which private methods are not being used. And regardless I don't think extra methods hanging around are a huge issue, more of a code smell.

    This answer **DOES NOT** answer the question. The question is **how** should private methods be tested, not **whether** they should be tested. Whether a private method should be unit tested is an interesting question and worthy of debate, but **not here**. The appropriate response is add a comment in the question stating that testing private methods may not be a good idea and give a link to a separate question which would go into the matter more deeply.

    @TallGuy Allow me to distill my answer here to its core point. The answer to "how does one unit test private methods?" is "One doesn't."

    How can I stub calling private method?

    @hellboy In what context? What does the private method you want to stub out do?

    if you use tdd,the test method generally test public or protected method

    @TallGuy though you are correct that this answer does not technically answer the asked question, it *does* answer the question the OP intended to ask (what he actually wanted vs. what he said he wanted). Math Student: How do I properly divide by 0? Math teacher: You don't. (Of course you can divide by 0 - in engineering mathematics - but proper guidance says you ought not to).

    @quant_dev: "If you paint yourself into a corner, you're going to have to walk on the paint" (which is valid, and what I suspect you mean) is not the same as "you have to sometimes walk on paint" (what you ended up implying). If the private method can be meaningfully tested by itself, then it is a unit in and of itself and warrants a class of its own. In your "valid" example, you're dealing with an overloaded class, a lack of single responsibilities and separation of concerns, and coupling that is way too tight. That's the corner you would've painted yourself in for your advice to apply.

    @hellboy: Stubbing something entails it being public knowledge, which is not what a private method is. As this answer explores, private methods are implementation details whose existence is not relevant to anyone but the owning class - stubs are decided by someone else who doesn't know of the private function and thus wouldn't know it should/needed to be stubbed.

    Also there is a sound argument that if you feel the need to test a private method then your class most likely is doing more than it should and thus breaking the Single Responsibility Principle. So it could be an oportunity to extract to a new class that method/behaviour.

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM