Los Techies : Blogs about software and anything tech!

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.

Kick It on DotNetKicks.com
Posted Nov 21 2008, 04:49 PM by chadmyers
Filed under: ,

Comments

Dew Drop – Weekend Edition – November 22-23, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop – Weekend Edition – November 22-23, 2008 | Alvin Ashcraft's Morning Dew
on 11-22-2008 10:05 PM

Pingback from  Dew Drop – Weekend Edition – November 22-23, 2008 | Alvin Ashcraft's Morning Dew

guy kolbis wrote re: Do not test private methods
on 11-24-2008 4:50 AM

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?

Thanks,

Guy Kolbis

Guy kolbis wrote Question: Test Private Methods
on 11-24-2008 4:55 AM

After reading Chad Myers post on Do not test private methods , I started thinking... I have always tested

bogardj wrote re: Do not test private methods
on 11-24-2008 7:14 AM

@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.

chadmyers wrote re: Do not test private methods
on 11-24-2008 9:24 AM

@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.

mbratton wrote re: Do not test private methods
on 11-24-2008 12:03 PM

What about protected methods?

Answer: Test Private Methods - Guy kolbis wrote Answer: Test Private Methods - Guy kolbis
on 11-25-2008 2:22 PM

Pingback from  Answer: Test Private Methods - Guy kolbis

chadmyers wrote re: Do not test private methods
on 11-25-2008 7:05 PM

@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 wrote re: Do not test private methods
on 11-26-2008 1:18 AM

Hi Chad,

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

blogs.microsoft.co.il/.../my-opinion-on-mocking.aspx

This is my opinion on mocking.

B.W

1) not testing a class? this is not TDD...

2) testing derive classses only?

Thanks

chadmyers wrote re: Do not test private methods
on 11-26-2008 9:14 AM

@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

Mark Needham wrote re: Do not test private methods
on 11-28-2008 8:55 PM

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.

Mark

TDD: If it’s hard to test reflect on your approach at Mark Needham wrote TDD: If it’s hard to test reflect on your approach at Mark Needham
on 11-30-2008 2:44 AM

Pingback from  TDD: If it’s hard to test reflect on your approach at Mark Needham

Doug Kent wrote re: Do not test private methods
on 01-08-2009 5:28 PM

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?

chadmyers wrote re: Do not test private methods
on 01-08-2009 10:29 PM

@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.

Garry Pilkington wrote Do you test your private methods?
on 02-18-2009 5:44 AM

There is ample discussion on the blogosphere as to why you should or shouldn't test your private methods

Developer News » Blog Archive » Windows 7 on the Dell Mini 9 with only the wrote Developer News » Blog Archive » Windows 7 on the Dell Mini 9 with only the
on 02-21-2009 4:08 AM

Pingback from  Developer News  » Blog Archive   »  Windows 7 on the Dell Mini 9 with only the

Copyright Los Techies 2008, 2009. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems