I'm building a class library that will have some public & private methods. I want to be able to unit test the private methods (mostly while developing, but also it could be useful for future refactoring).

I may be missing something, or maybe it's just that this question is, well... pre-historic in term of Internet years, but unit testing of private methods is now both easy and straight forward, with Visual Studio producing the necessary accessor classes when needed and pre-filling the tests logic with snippets damn close to what one may desire for simple functional tests. See for eg. msdn.microsoft.com/en-us/library/ms184807%28VS.90%29.aspx
– mjvAug 10 '11 at 23:00

@Jay - couldn't one use #if DEBUG around the InternalsVisibleTo attribute to make it not apply to release code?
– mpontilloDec 1 '10 at 21:42

20

@Mike, you could, but then you can only run unit tests on debug code, not release code. Since Release code is optimized, you might see different behavior and different timings. In multithreaded code this means your unit tests won't appropriately detect race conditions. Much better is to use reflection via @AmazedSaint's suggestion below or use the built-in PrivateObject/PrivateType. This allows you to see privates in Release builds assuming your test harness is running with full trust (which MSTest running locally does)
– JayDec 9 '10 at 3:16

118

What am I missing? Why would this be the accepted answer when it doesn't actually answer the specific question of testing private methods? InternalsVisibleTo only exposes methods marked as internal and not those marked private as requested by the OP (and the reason I landed here). I guess I need to continue using PrivateObject as answered by Seven?
– Darren LewisMay 25 '11 at 13:34

5

@Jay I know this is a bit late-coming, but one option is to use something like #if RELEASE_TEST around InternalsVisibleTo like Mike suggests, and make a copy of your release build configuration that defines RELEASE_TEST. You get to test your release code with optimizations, but when you actually build for release, your tests will be omitted.
– ShazJul 24 '13 at 17:52

If you want to unit test a private method, something may be wrong. Unit tests are (generally speaking) meant to test the interface of a class, meaning its public (and protected) methods. You can of course "hack" a solution to this (even if just by making the methods public), but you may also want to consider:

If the method you'd like to test is really worth testing, it may be worth to move it into its own class.

Add more tests to the public methods that call the private method, testing the private method's functionality. (As the commentators indicated, you should only do this if these private methods's functionality is really a part in with the public interface. If they actually perform functions that are hidden from the user (i.e. the unit test), this is probably bad).

Option 2 makes the unit tests have to have knowledge of the underlying implementation of the function. I don't like doing that. I generally think unit tests should test the function without assuming anything about implementation.
– HermsOct 30 '08 at 16:01

15

Disadvantages of testing implementation is that the tests will be fragile to break if you introduce any changes to the implementation. And this is undesirable as refactoring is as important as writing the tests in TDD.
– JtROct 30 '08 at 16:04

30

Well, the tests are supposed to break if you change the implementation. TDD would mean changing the tests first.
– sleskeApr 22 '09 at 17:11

39

@sleske - I don't quite agree. If the functionality hasn't changed, then there's no reason the test should break, since tests should really be testing behaviour/state, not implementation. This is what jtr was meaning about it making your tests fragile. In an ideal world, you should be able to refactor your code and have your tests still pass, verifying that your refactoring hasn't changed the functionality of your system.
– AlconjaMay 28 '09 at 0:10

24

Apologies for naivety (not much experience with testing as yet), but isn't the idea of unit testing to test every code module on its own? I don't really understand why private methods should be excluded from this idea.
– OMillJun 9 '11 at 10:59

It might not be useful to test private methods. However, I also sometimes like to call private methods from test methods. Most of the time in order to prevent code duplication for test data generation...

Microsoft provides two mechanisms for this:

Accessors

Goto the class definition's source code

Right-click on the name of the class

Choose "Create Private Accessor"

Choose the project in which the accessor should be created
=> You will end up with a new class with the name foo_accessor.
This class will be dynamically generated during compilation and privides all members public available.

However, the mechanism is sometimes a bit intractable when it comes to changes of the interface of the original class. So, most of the times I avoid using this.

PrivateObject class
The other way is to use Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject

@RyanGates The first solution on the site you referenced states that the solution to access private members is to "Use the PrivateObject class to assist in accessing internal and private APIs in your code. This is found in the Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll assembly."
– stackunderflowNov 26 '13 at 23:40

I don't agree with the "you should only be interested in testing the external interface" philosophy. It's a bit like saying that a car repair shop should only have tests to see if the wheels turn. Yes, ultimately I'm interested in the external behavior but I like my own, private, internal tests to be a bit more specific and to the point. Yes, if I refactor, I may have to change some of the tests, but unless it's a massive refactor, I'll only have to change a few and the fact that the other (unchanged) internal tests still work is a great indicator that the refactoring has been successful.

You can try to cover all internal cases using only the public interface and theoretically it's possible to test every internal method (or at least every one that matters) entirely by using the public interface but you may have to end up standing on your head to achieve this and the connection between the test cases being run through the public interface and the internal portion of the solution they're designed to test may be difficult or impossible to discern. Having pointed, individual tests that guarantee that the internal machinery is working properly is well worth the minor test changes that come about with refactoring - at least that's been my experience. If you have to make huge changes to your tests for every refactoring, then maybe this doesn't make sense, but in that case, maybe you ought to rethink your design entirely. A good design should be flexible enough to allow for most changes without massive redesigns.

I'm afraid I still disagree with you. Treating each component as a black box allows modules to be swapped in/out without problems. If you have a FooService that has to do X, all you should care about is that it does indeed do X when requested. How it does it shouldn't matter. If there are problems in the class not discernible through the interface (unlikely), it's still a valid FooService. If it's a problem that is visible through the interface, a test on public members should detect it. The whole point should be that as long as the wheel turns properly, it can be used as a wheel.
– BasicOct 24 '12 at 16:41

5

One general approach is that if your internal logic is complicated enough that you feel it requires unit testing, perhaps it needs to be extracted into some kind of helper class with a public interface that can be unit tested. Then your 'parent' class can simply make use of this helper, and everyone can be unit tested appropriately.
– MirFeb 8 '13 at 23:50

9

@Basic: Completely wrong logic in this answer. Classic case when you need private method is when you need some code to be reused by public methods. You put this code to some PrivMethod. This method should not be exposed to public, but needs testing to assure that public methods, which rely on PrivMethod, can really rely on it.
– DimaApr 8 '13 at 13:45

6

@Dima Surely then if there's a problem with PrivMethod, a test on PubMethod which calls PrivMethod should expose it? What happens when you change your SimpleSmtpService to a GmailService? All of a sudden your private tests are pointing at code that no longer exists or perhaps works differently and would fail, even though the application may work perfectly as designed. If there's complex processing that would apply to both email senders, perhaps it should be in an EmailProcessor which can be used by both and tested separately?
– BasicApr 8 '13 at 14:47

2

@miltonb We may be looking at this from different development styles. WRT the internals, I don't tend to unit test them. If there's a problem (as identified by interface tests), it's either easy to track down by attaching a debugger or the class is too complex and should be split up (with the public interface of the new classes unit tested) IMHO
– BasicFeb 18 '14 at 0:49

I think a more fundamental question should be asked is that why are you trying to test the private method in the first place. That is a code smell that you're trying to test the private method through that class' public interface whereas that method is private for a reason as it's an implementation detail. One should only be concerned with the behaviour of the public interface not on how it's implemented under the covers.

If I want to test the behaviour of the private method, by using common refactorings, I can extract its code into another class (maybe with package level visibility so ensure it's not part of a public API). I can then test its behaviour in isolation.

The product of the refactoring means that private method is now a separate class that has become a collaborator to the original class. Its behaviour will have become well understood via its own unit tests.

I can then mock its behaviour when I try to test the original class so that I can then concentrate on test the behaviour of that class' public interface rather than having to test a combinatorial explosion of the public interface and the behaviour of all its private methods.

I see this analogous to driving a car. When I drive a car I don't drive with the bonnet up so I can see that the engine is working. I rely on the interface the car provides, namely the rev counter and the speedometer to know the engine is working. I rely on the fact that the car actually moves when I press the gas pedal. If I want to test the engine I can do checks on that in isolation. :D

Completely wrong logic in this answer. Classic case when you need private method is when you need some code to be reused by public methods. You put this code to some PrivMethod. This method should not be exposed to public, but needs testing to assure that public methods, which rely on PrivMethod, can really rely on it.
– DimaApr 8 '13 at 13:45

Makes sense during initial development, but do you want tests for private methods in your standard regression suit? If so, if the implementation changes, it can break the test suite. OTOH, if your regression tests focus only on externally visible public methods, then if the private method breaks later, the regression suite should still detect the error. Then if necessary, you can dust off the old private test if needed.
– Alex BlakemoreJul 9 '13 at 0:51

9

Disagree, you should be testing the public interface only, else why the need for private methods. Make them all public in that case and test all of them.If you're testing private methods you're breaking enscapulation. If you want to test a private method and it's used in multiple public methods then it should be moved to its own class and tested in isolation.All the public methods should then delegate to that new class.In that way you still have tests for the original class' interface and you can verify the behaviour hasn't changed and you have separate tests for the delegated private method.
– Big KahunaJul 24 '13 at 13:35

@Big Kahuna - If you think there is no case where you need to unit test private methods you never worked with a big/complex enough project. Lots of times a public function like client specific validations end up with 20 lines just calling very simple private methods to make the code more readable but you still have to test each individual private method. Testing 20 times the public function will make it very difficult to debut when the unit tests fail.
– Pedro.The.KidOct 27 '17 at 10:27

1

I work for a FTSE 100 company. I think I've seen several complex projects in my time, thank you. If you need to test to that level, then each private method as separate collaborators, should be tested in isolation because it implies they have individual behaviour that needs testing. The test for the main mediator object then just becomes a interaction test. It just test the correct strategy is being called.Your scenario sounds like the class in question is not following SRP. It does not have a single reason to change but 20 => SRP violation. Have a read of GOOS book or Uncle Bob. YMWV
– Big KahunaNov 9 '17 at 19:17

Private types, internals and private members are so because of some reason, and often you don’t want to mess with them directly. And if you do, chances are that you’ll break later, because there is no guarantee that the guys who created those assemblies will keep the private/internal implementations as such.

But ,at times, when doing some hacks/exploration of compiled or third party assemblies, I have myself ended up wanting to initialize a private class or a class with a private or internal constructor. Or, at times, when dealing with pre-compiled legacy libraries that I can’t change - I end up writing some tests against a private method.

I've also used the InternalsVisibleToAttribute method. It's worth mentioning too that, if you feel uncomfortable making your previously private methods internal in order to achieve this, then maybe they should not be the subject of direct unit tests anyway.

After all, you're testing the behaviour of your class, rather than it's specific implementation - you can change the latter without changing the former and your tests should still pass.

I love the point about testing behavior rather than implementation. If you tie your unit tests to implementation (private methods), then the tests will become brittle and need to change when the implementation changes.
– Bob HornJun 11 '17 at 23:29

The gen'd files only exist in VS2005. IN 2008 they're generated behind the scenes. And they're an abmomination. And the associated Shadow task is flaky on a build server.
– Ruben BartelinkFeb 12 '10 at 9:22

On CodeProject, there is an article that briefly discusses pros and cons of testing private methods. It then provides some reflection code to access private methods (similar to the code Marcus provides above.) The only issue I've found with the sample is that the code doesn't take into account overloaded methods.

I tend not to use compiler directives because they clutter things up quickly. One way to mitigate it if you really need them is to put them in a partial class and have your build ignore that .cs file when making the production version.

You would include the test accessors in a production version (to test compiler optimizations etc) but exclude them in a release version. But I'm splitting hairs & I upvoted this anyway because I think it's a good idea to put that stuff in a single place. Thanks for the idea.
– CAD blokeNov 6 '13 at 10:49

You should not be testing the private methods of your code in the first place. You should be testing the 'public interface' or API, the public things of your classes. The API are all the public methods you expose to outside callers.

The reason is that once you start testing the private methods and internals of your class you are coupling the implementation of your class (the private things) to your tests. This means that when you decide to change your implementation details you will also have to change your tests.

Sometimes, it can be good to test private declarations.
Fundamentally, a compiler only has one public method: Compile( string outputFileName, params string[] sourceSFileNames ). I'm sure you understand that would be difficult to test such a method without testing each "hidden" declarations!

That's why we have created Visual T#: to make easier tests. It's a free .NET programming language (C# v2.0 compatible).

We have added '.-' operator. It just behave like '.' operator, except you can also access any hidden declaration from your tests without changing anything in your tested project.

I'm surprised nobody has said this yet, but a solution I have employed is to make a static method inside the class to test itself. This gives you access to everything public and private to test with.

Furthermore, in a scripting language (with OO abilities, like Python, Ruby and PHP), you can make the file test itself when run. Nice quick way of making sure your changes didn't break anything. This obviously makes a scalable solution to testing all your classes: just run them all. (you can also do this in other languages with a void main which always runs its tests as well).

Although this is practical, it's not very elegant. This can create a bit of a mess of a code base and also doesn't allow you to separate out your tests from your real code. The ability to test externally opens up the ability to script automate testing instead of writing static methods by hand.
– Darren ReidJun 6 '11 at 10:32

This does not preclude you from testing externally...just call the static method however you like. The code base is also not messy...you name the method accordingly. I use "runTests", but anything similar works.
– rubeJun 6 '11 at 21:44

Your right, it doesn't preclude from testing externally, however it does generate a lot more code,ie make the code base messy. Each class might have a lot of private methods to test which initialises it's variables in one or more of its constructors. To test, you are going to have to write at least as many static methods as there are methods to test, and the test methods may have to be large to initialise the right values. This would make the maintenance of code more difficult. As others have said, testing the behaviour of a class is a better approach, the rest should be small enough to debug.
– Darren ReidJun 6 '11 at 22:09

I use the same number of lines to test as anyone else (actually less as you'll read later). You don't have to test ALL your private methods. Just the ones which need testing :) You also don't need to test each one in a separate method. I do it with one call. This actually make the maintenance of the code LESS difficult, since all my classes have the same umbrella unit test method, which runs all the private and protected unit tests line by line. The entire test harness then calls that same method on all my classes and the maintenance all resides within my class - tests and all.
– rubeJun 9 '11 at 0:11

Regarding the "test private" I agree that.. in the perfect world. there is no point in doing private unit tests. But in the real world you might end up wanting to write private tests instead of refactoring code.

Here is good article about unit testing of private methods. But I'm not sure what's better, to make you application designed specially for testing(it's like creating tests for testing only) or use reflexion for testing.
Pretty sure most of us will choose second way.

What is this? Does this apply to Visual Studio?
– YeahStuFeb 19 '09 at 13:39

"CC" is the command line compiler on the system I use. "-Dfoo=bar" does the equivalent of "#define foo bar". So, this compilation option effectively changes all private stuff to public. ha-ha!
– Mark HarrisonFeb 19 '09 at 19:44

I don't agree with this one, because you will also allow your consumers to inherit from the base class and use the protected functions. This was somehting you wanted to prevent in the first place by making those functions private or internal.
– Nick N.Nov 17 '15 at 12:21

1) If you have a legacy code then the only way to test private methods is by reflection.

2) If it is new code then you have the following options:

Use reflection (to complicated)

Write unit test in the same class (makes the production code ugly by
having test code also in it)

Refactor and make the method public in some kind of util class

Use @VisibleForTesting annotation and remove private

I prefer the annotation method, simplest and least complicated. The only issue is that we have increased the visibility which I think is not a big concern.
We should always be coding to interface, so if we have an interface MyService and an implementation MyServiceImpl then we can have the corresponding test classes that is MyServiceTest (test interface methods) and MyServiceImplTest (test private methods). All clients should anyway be using the interface so in a way even though the visibility of the private method has been increased it should not really matter.

This should be the right answer IMO. If you have lots of private methods then this is probably because you have a hidden class that you should break out into its own public interface.
– sunefredJan 23 '17 at 16:54

You could generate the test method for the private method from Visual studio 2008. When you create a unit test for a private method, a Test References folder is added to your test project and an accessor is added to that folder. The accessor is also referred to in the logic of the unit test method. This accessor allows your unit test to call private methods in the code that you are testing.
For details have a look at

Also note that the InternalsVisibleToAtrribute has a requirement that your assembly be strong named, which creates it's own set of problems if you're working in a solution that had not had that requirement before. I use the accessor to test private methods. See this question that for an example of this.

Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).