Question

I am trying to unit test a class that has public and private methods and I want to unit test a particular method that has been set as private (protected abstract on the base). I cannot make the method public and I do not want to go through the full process to get this method tested, I am only concerned that the input argument to this method and the return meet an expectation.

I do not want to make the method public as this question highlights:

Making a private method public to unit test it...good idea?

My question would be, what are the various ways of testing private methods and which technique should I favour and why?

I have read this question (How do you unit test private methods?) but would like to know if the accepted answer is still the best answer or after years there is a better way.

If this question is considered a duplicate of How do you unit test private methods? I will add my comment there and ask for an update, please advise.

Était-ce utile?

La solution 4

Do you want to be able to call your private method in test and see how it works?

You can derive from your class and add public method that will call method you want to test. Very simple. Although I wouldn't advice testing private methods. I can't think of single reason to do it. I would love to see example that will change my mind.

Edit: Since this answer still gets some traffic I share this link. This blog post was created around 4 years after I posted my answer: https://enterprisecraftsmanship.com/posts/unit-testing-private-methods/

Autres conseils

If you can't meaningfully test the private methods of a class via the public methods then that would suggest something is wrong with the design of the class. If it is hard to test the class so that you wish to break down the tests to test a subset of its functionality then I would suggest breaking the class into its logical pieces and testing those individually.

Perhaps you have an opportunity to refactor the code so that the private methods become the public methods of some other class(es). A good example is a class that schedules some work on a timer to be processed at a later time. The work method would likely be implemented as private method making it difficult to test in a simple way without scheduling a timer and waiting around for it to execute the work method. Not ideal in a test where execution times should be very quick. A simple way around this is to split the scheduling work code into two seperate classes. The private work method then becomes the public method of the Worker class making it very easy to test. Whilst splitting the scheduling and worker code means you will struggle to achieve 100% coverage, you will at least cover the work code. A way around the problem is to use something like Quartz.net for implementing the scheduler class so that you can unit test the scheduler quite easily and the worker code as well.

I have read this question (How do you unit test private methods?) but would like to know if the accepted answer is still the best answer or after years there is a better way.

I would avoid the accepted answer.

I can jump into a tirade about testing the public interface and not worrying about the internals, but that might not be realistic.

There are two immediate options I can see:

  • Reflection to see the method, sort of a hack, but at least you can get some sort of test going. This is also likely the easiest to get working quickly.
  • Abstract the private method behaviour using something like the Strategy pattern and inject the behaviour into the object itself (or have the object internally new up the relevant strategy manually). This separate strategy item can then be tested independently.

That said, you shouldn't find yourself in this situation very often. If you do, you need to take a step back and review how you are designing your classes and possibly review them with a view to making them more open and testable.

In VS 2005, 2008 and 2010, you may have private accessor. You right click on a private function, and select "Create private accessor" ...

In VS 2012, this feature had somehow gone. The only handy way is to use PrivateObject. You may check MSDN for examples of using PrivateObject.

Use reflection. If you don't want to mess with reflection yourself, then you can use Microsoft's PrivateObject class located in Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll. But there are problems in cooperating MSTest and NUnit - Using both MSTest and NUnit?

If you are using VS 2005 or above, use following steps

  1. Open a source code file that contains a private method.
  2. Right-click the private method, and select Create Unit Tests. This displays the Create Unit Tests dialog box. In the visible tree structure, only check box for the private method is selected.
  3. (Optional) In the Create Unit Tests dialog box, you can change the Output project. You can also click Settings to reconfigure the way unit tests are generated.
  4. Click OK. This creates a new file named VSCodeGenAccessors, which contains special accessor methods that retrieve values of private entities in the class being tested. You can see the new file displayed in Solution Explorer in the test project folder. If your test project had no unit tests before this point, a source code file to house unit tests is also created. As with the file that contains private accessors, the file that contains unit tests is also visible in your test project in Solution Explorer.
  5. Open the file that contains your unit tests and scroll to the test for the private method. Find the statements that are marked with // TODO: comments and complete them by following the directions in the comments. This helps the test produce more accurate results

For more information refer this

It looks that internally it uses reflection to call private method. But it works.

I actually came here for an answer to this question until I realized that I shouldn't be unit testing private methods. The reason for this, is because private methods are a piece in a process that is part of some larger logic.

Unit tests are intended to test against the interface of a class. The idea is that I am supposed to ensure quality control when using my class in the way that it is intended to. As a result, it's not useful to unit test a private method, simply because it will never be exposed to the consumer (whoever is implementing). You need to unit test against cases which the consumer can use your class.

If you find yourself with the absolute need to unit test something that is private, you might need to rethink the location of that method, or how your code is broken down. I've come to the conclusion that if I need to unit test a private method, 9/10 times it's a method that can be wrapped into a static utility class.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top