What is the best practice for individual testing methods in .NET?

Recently, to implement unit testing for a private class method, I used PrivateObject to create private accessories instead of using Reflection , which I received the following comment for checking the code:

"My main problem with Private Object is to use the [] object in the constructor. It replaces the strong typing used by the compiler to detect errors during JavaScript execution. Therefore, I personally would not recommend it."

This comment above has confused me according to my understanding, Reflection also needs an object[] to call any method. Please help me figure out which is the best approach.

+4
source share
4 answers
  • You can use special classes that inherit classes with private (now protected) methods and methods that are called invisible from outside protected methods.

This is called a test specific subclass or test specific extension in the large test refactoring code book of http://xunitpatterns.com/

You can read more detailed information and ideas for testing personal methods here: http://xunitpatterns.com/Test-Specific%20Subclass.html

It works like

 public TestClass : RealClass { public int CallHiddenCalculate() { return Calculate(); // Calculate is now protected method that we expose for test purposes in this class } } 

You can put this class in a test assembly so that your real assembly does not contain test logic and classes, because its design is poor.

  • You can also use conditional compilation for the visibility attribute, as shown below.
  #if DEBUG
         public
     #else
         private
     #endif

In this case, you can call unit tests in Debug, but these methods will not be visible in the release. However, this approach is much worse than higher, and is more ugly.

Testing only the public interface may not be enough (and often it is not) to say that you got good coverage for testing, and your code is easy to maintain and refactor.

As regards marking private methods as internal and assembly tests, see internal methods, this is bad for many reasons.

  • Your previous private methods are visible from your assembly because they are internal
  • you will have a certain logic of the test (internal for these methods will be for testing purposes only) in the release version of your product, which is bad

and I think there are more of them, but they are most important

+6
source

Interest Ask. As a rule, unit tests are designed to test the social behavior of your classes from the point of view of consumers of your classes. That is, consumers do not care how you do it if your class keeps promises.

If you really need to provide 'private' to unit test members, mark them as internal and make them available through the InternalsVisibleTo attribute. This is ugly, but it works, and you can later save it from your assembly with some conditional compilation.

+4
source

You are correct that using reflection has the same problems as using a PrivateObject template. The best solution is to not try to specifically test private methods.

+2
source

If you use Gallio / MbUnit , you can consider the built-in Mirror .

Sometimes, the most obvious way to write a test is to access a non-public state or behavior. This may not be the best way to write a test, but for now it may seem like the easiest solution. MbUnit provides several classes to help access non-public members.

0
source

Source: https://habr.com/ru/post/1340912/


All Articles