Do not test private methods

You should only be testing public methods. Private methods are an implementation detail of the object and are subject to heavy change, etc.  Any class, including test fixtures, that care about private methods on another object exhibit the “Inappropriate intimacy” code smell stench.

If you find the need to test a private method, then you’re doing something else wrong. There is an “upstream” problem, so to speak. You have arrived at this problem due to some other mistake previous in this process.  Try to isolate what that is, exactly, and remove that rather than bending your tests to go down a painful road of brittleness in testing.

Better yet, consider why you even need those private methods in the first place.  Why do you feel you need to test them? Is there some major functionality there worth testing? Maybe it shouldn’t be private?  Maybe you have a “responsibility violation” (a violation of the Single Responsibility Principle)?  Maybe you should break this functionality into another class?  There is no one right answer, it depends on your situation so judge accordingly.

In general, don’t let yourself fall into the “It’s legacy code, I can’t do anything” mental trap. There is usually something you can do. For example,  extract class and inject it, make the method public, etc.  If all else fails (and please try not to just give up here, give it a college try), then you can fall back to extraordinary means.

About Chad Myers

Chad Myers is the Director of Development for Dovetail Software, in Austin, TX, where he leads a premiere software team building complex enterprise software products. Chad is a .NET software developer specializing in enterprise software designs and architectures. He has over 12 years of software development experience and a proven track record of Agile, test-driven project leadership using both Microsoft and open source tools. He is a community leader who speaks at the Austin .NET User's Group, the ADNUG Code Camp, and participates in various development communities and open source projects.
This entry was posted in TDD, Tips. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Hi Chad,
    Thanks for sharing this. Is this your opinion or Microsoft?
    If this is the case why did Microsoft created the Private accessors in Visual Studio?
    What about internal methods?
    Guy Kolbis

  • @guy

    the general rule of thumb is only test public visible behavior. If you feel you need to test something private, then your class probably has too much responsibility.

    The other piece to note is that private methods are generally only testable through reflection, which uses strings, which is brittle. InternalsVisibleTo attribute is a means around this issue, which I had to use quite a bit when part of our shipped product was a public API.

  • @guy:

    Microsoft’s opinion is in favor of testing private methods. In fact, they seem to encourage it with, like you said, Private Accessors and various How To articles on MSDN.

    I wouldn’t say that this is just my opinion, it is generally a common-held opinion in the unit testing and, specifically, TDD circles. I won’t take credit for this thought, but I will say that I do hold this opinion (e.g “Do not test private methods”).

    I have written several large-scale enterprise apps and have not ever needed to test a private method. I’m saying this to brag or anything, I’m saying it to prove a point that it IS possible and SHOULD be a virtue worth striving for.

    Having said all this, I am not prepared to say that testing private methods is ALWAYS wrong, but it’s “ALMOST ALWAYS” wrong. There may be a few circumstances where it is beneficial or worth the risk of brittle tests to do this.

    This is why I called it a code “stench”. It’s worse than a smell, but it’s not universally BAD.

    RE: Internal methods

    I feel mostly the same about this one, but it’s not quite as dangerous as private methods, so I would tone down a the warning a little. Generally, I manage to find a way to not have any internal methods also.

    Internal methods usually denote direct coupling between concrete classes versus coupling through abstractions (public interfaces). This creates a more brittle framework and prevents client code from overriding functionality if it needs to.

    By using the Dependency Inversion Principle and Interface Segregation Principle, along with an IoC container, I seem to never need the ‘internal’ keyword and very rarely need the ‘private’ keyword, let alone tests for the same.

  • What about protected methods?

  • @mbratton

    Protected methods are protected methods for a reason (i.e. you’re exposing them to client code — whether your own client code or the wide, wide world’s client code).

    So, I would give the following advice:

    If it is 100% your code on both sides (framework/infrastructure code and client code) and the code in this project or other projects under your control (i.e. not code that will be used by a wide audience), I would concentrate on testing the classes that derive from the class-with-protected-members and you will essentially be testing the protected method(s) in question.

    Having said that, if you find your tests repeating themselves for each sub-class, perhaps it would be better to have a test subclass that exposes the protected functionality and test that instead (to avoid duplication/repetition).

    If this is a public framework where anyone and everyone is going to derive from your class and use this protected method, I would use the test subclass or a PartialMock (most mocking frameworks can do this — see Rhino Mocks, Moq, TypeMock, etc).

  • guy kolbis

    Hi Chad,
    I enjoy reading your comments, however I have some issue with some, first please read this:

    This is my opinion on mocking.

    1) not testing a class? this is not TDD…
    2) testing derive classses only?


  • @guy:

    (1) “not testing a class” — I don’t follow. Please elaborate. In C#, it is not possible to write code without a class (for the most part, there are tricks), so I don’t know how you could not test a class. And I do this and it is TDD, so I don’t know what you mean.

    (2) “testing derived classes only” – Meaning: Test the public API first unless it gets repetitive and you start violating DRY, then consider testing the protected method directly

  • You’re right that you shouldn’t test private methods although I’ve sometimes found that when I’ve made a class way too big and difficult to test that it can be effective to make a private method public temporarily and test it in there before I work out where I want to move it to.

    I’m not sure whether or not that’s a bad approach – certainly if I leave it in that state it’s not good at all, but it helps to keep the momentum and I can then move the method to the right place when I’ve finished working on the original class.


  • Doug Kent

    I’m not convinced that one should not test private methods. The argument for that seems to be of the form that one should not test them because one should not test them, or, private methods cannot possibly represent a valid or respectable unit of testable code, because they can’t.

    Other than being not swayed by this, it seems absurd to me. What is it about being “private” that necessarily makes a piece of code not worthy of a unit test being dedicated to it? Of course a private method can accomplish a very useful and well encapsulated task pertinent only to a single class. Why must that task necessarily be public?

  • @Doug: Let me turn the question around on you: Why must that task necessarily be private?

    Frankly, I don’t frequently find the need to make hardly anything private. Classes are small, singularly responsible, methods are small, and generally only a few methods per class. If I do need a private method, it’s usually a small utility method of some sorts.

    So your private methods are either a.) Used heavily by the public members in the class or b.) not used.

    If a.) then they’ll get tested when you test the public methods and b.) why are they there in the first place, let alone being tested?

    And if your private methods are complex enough you really feel the need to test them separately, then you probably have a design smell or problem somewhere else you need to investigate.

    This is the kind of stuff I like using TDD for, because it helps remind me when I’m making mistakes. When I have lots of stuff in a private method, TDD gently, but firmly, reminds me where I went wrong and how to correct it.

  • Anonymous

    i truthfully enjoy your own writing kind, very remarkable,
    don’t give up as well as keep writing due to the fact that it simply just worth to follow it. looking forward to see a whole lot more of your current well written articles, enjoy your day
    SEO Services Company