Testing Private & Protected Members of a Class

In my last blog post, someone asked me you can write unit tests for a private or protected method.  I gave part of the response in a comment, but I need to give a more detailed description.

Focus on the public API of your system

First and foremost, I focus on testing the public API.  You should be able to test all of the code branches in your private methods by adequately testing the public methods in your system.  Using tools like NCover can help you analyze how well your tests are actually testing your system.  I don’t try to get 100% coverage, but I typically have above 80% as a normal target.

Testing Protected Members

There are times when you do need to test protected members of a class.  If you are inheriting from a class that you do have the source code to (like say Controller) and you override a protected method, it is possible to test that.  While it should be possible to test protected member through the public api, it is relatively simple to do it and doesn’t really break any encapsulation rules in your application.

It is actually very easy.  All you need to do is create a test class that inherits from you and add a public method that call the protected method in question.  Here is an example.

public class ClassWithProtectedMember
    {
        
protected int UltimateQuestionAnswer() { return 42; }
    }

    public class ProtectedMemberAccessor : ClassWithProtectedMember
    {
        
public int ExecuteUltimateQuestionAnswer(){
            
return base.UltimateQuestionAnswer();}
    }
    [
TestFixture]
    
public class ProtectedMemberSpecs {

        [Test]
        
public void should_give_us_the_answer_to_life_universe_and_everything()
        {
            
var wrapper = new ProtectedMemberAccessor();
            
Assert.That(wrapper.ExecuteUltimateQuestionAnswer(),Is.EqualTo(42));
        }
    

This is a very simple and straightforward approach, but is very effective in testing some hidden members in you system.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

This entry was posted in c#, Testing. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • pablo

    I asked you this question yesterday and in the meantime @KentBeck replied to my tweet about that too.

    His words: http://twitter.com/KentBeck/status/3579860805
    @pablogl i only test public methods. if a private method is complex enough to need testing, it generally needs its own object.

    In other words, if the private/protected method is really so important that you have to test it, then perhaps we are violating the Single Responsibility Principle.

  • http://www.lostechies.com/members/jcteague/default.aspx jcteague

    @pablo
    That’s absolutely true. The times when I needed to test a protected member I’m sure I was violating SRP. The most recent need for me to do so was overrided a member on the Controller class. I’m not sure I had a way to do in a way without violating SRP since I do not own the Controller class.

  • ctasada

    You can find a different approach for the same problem here:

    http://ctasada.blogspot.com/2009/08/junit-how-to-test-your-private-methods.html

  • http://www.lostechies.com/members/jcteague/default.aspx jcteague

    @ctasada
    yes, reflection is an option. MSTest actually creates a helper class for you that gives you access to all of your methdods for you.

    However I agree with the comment pablo made that if they are really that complex, chances are you’re missing an abstraction somewhere in your design.

  • http://jasonmbaker.wordpress.com Jason Baker

    Interesting post. I’ve outlined a few ways of looking at the “how do I test private methods” question here: http://jasonmbaker.wordpress.com/2009/01/08/enemies-of-test-driven-development-part-i-encapsulation/

  • http://www.lostechies.com/members/jcteague/default.aspx jcteague

    @Jason
    I liked your post. It reminded me of something I should have mentioned in my original post. I guess that means I should write a new one huh?

  • http://www.bmbvideo.com/acomplia.html arialnormalg

    propecia online [url="http://www.bmbvideo.com/propecia.html"]propecia online[/url] http://www.bmbvideo.com/propecia.html propecia online buy ambien [url="http://www.bmbvideo.com/ambien.html"]buy ambien[/url] http://www.bmbvideo.com/ambien.html buy ambien order acomplia [url="http://www.bowlinginlubbock.com/Acomplia.htm"]order acomplia[/url] http://www.bowlinginlubbock.com/Acomplia.htm order acomplia