How do you unit test private methods?

前端 未结 30 1449
无人及你
无人及你 2020-11-22 06:44

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 coul

相关标签:
30条回答
  • 2020-11-22 07:46

    In the rare cases I have wanted to test private functions, I have usually modified them to be protected instead, and the I have written a subclass with a public wrapper function.

    The Class:

    ...
    
    protected void APrivateFunction()
    {
        ...
    }
    
    ...
    

    Subclass for testing:

    ...
    
    [Test]
    public void TestAPrivateFunction()
    {
        APrivateFunction();
        //or whatever testing code you want here
    }
    
    ...
    
    0 讨论(0)
  • 2020-11-22 07:46

    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

    Of course testing private methods directly may be a last resort if you have a legacy application but I would prefer that legacy code is refactored to enable better testing. Michael Feathers has written a great book on this very subject. http://www.amazon.co.uk/Working-Effectively-Legacy-Robert-Martin/dp/0131177052

    0 讨论(0)
  • 2020-11-22 07:46

    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.

    You should for this reason avoid using InternalsVisibleToAtrribute.

    Here is a great talk by Ian Cooper which covers this subject: Ian Cooper: TDD, where did it all go wrong

    0 讨论(0)
  • 2020-11-22 07:47

    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.

    Take a look at our web site: download it for free.

    0 讨论(0)
  • 2020-11-22 07:47

    A way to do this is to have your method protected and write a test fixture which inherits your class to be tested. This way, you are nor turning your method public, but you enable the testing.

    0 讨论(0)
  • 2020-11-22 07:48

    There are 2 types of private methods. Static Private Methods and Non Static Private methods(Instance Methods). The following 2 articles explain how to unit test private methods with examples.

    1. Unit Testing Static Private Methods
    2. Unit Testing Non Static Private Methods
    0 讨论(0)
提交回复
热议问题