Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing C# protected methods

I come from the Java EE world but now I'm working on a .Net project. In Java when I wanted to test a protected method it was quite easy, just having the test class with the same package name was enough.

Is there anything similar for C#? Is there any good practice for unit testing the protected methods? I only found frameworks and people saying that I should test only public methods.

It should be possible to do it without any framework…

like image 317
fiso Avatar asked Nov 16 '12 12:11

fiso


People also ask

What is unit testing C?

A Unit Testing Framework for C CUnit is a lightweight system for writing, administering, and running unit tests in C. It provides C programmers a basic testing functionality with a flexible variety of user interfaces. CUnit is built as a static library which is linked with the user's testing code.

Does C have unit testing?

The most scalable way to write unit tests in C is using a unit testing framework, such as: CppUTest. Unity. Google Test.

What do unit tests do?

The main objective of unit testing is to isolate written code to test and determine if it works as intended. Unit testing is an important step in the development process, because if done correctly, it can help detect early flaws in code which may be more difficult to find in later testing stages.

Which framework is used for unit testing of C++ programs?

The Microsoft Unit Testing Framework for C++ is included by default in the Desktop Development with C++ workload.


7 Answers

You can inherit the class you are testing on your test class.

[TestClass]
public class Test1 : SomeClass
{
    [TestMethod]
    public void MyTest
    {
        Assert.AreEqual(1, ProtectedMethod());
    }

}
like image 180
unarity Avatar answered Oct 02 '22 06:10

unarity


Another option is to use internal for these methods and then use InternalsVisibleTo to allow your test assembly to access these methods. This does not stop the methods being consumed by other classes in the same assembly, but it does stop them being accessed by other assembles that are not your test assembly.

This does not give you as much encapsulation and protection but it's pretty straight forward and can be useful.

Add to AssemblyInfo.cs in the assembly containing the internal methods

[assembly: InternalsVisibleTo("TestsAssembly")]
like image 24
Richard Garside Avatar answered Oct 04 '22 06:10

Richard Garside


You can expose the protected methods in a new class that inherits the class you want to test.

public class ExposedClassToTest : ClassToTest
{
    public bool ExposedProtectedMethod(int parameter)
    {
        return base.ProtectedMethod(parameter);
    }
}
like image 22
typhon04 Avatar answered Oct 04 '22 06:10

typhon04


You can use PrivateObject class to access all the private/ protected methods/ fields.

PrivateObject is a class in the Microsoft unit testing framework which is a wrapper that enables calling normally inaccessible members for unit testing.

like image 33
Usama Aslam Avatar answered Oct 02 '22 06:10

Usama Aslam


You can use reflection to invoke private and protected methods.

See here for more:

http://msdn.microsoft.com/en-us/library/66btctbe.aspx

like image 38
Justin Harvey Avatar answered Oct 01 '22 06:10

Justin Harvey


Although the accepted answer is the best one, it didn't solve my problem. Deriving from the protected class polluted my test class with a lot of other stuff. In the end I chose to extract the to-be-tested-logic into a public class and test that. Surely enough this will not work for everyone and might require quite some refactoring, but if you scrolled all the way up to this answer, it might just help you out. :) Here's an example

Old situation:

protected class ProtectedClass{
   protected void ProtectedMethod(){
      //logic you wanted to test but can't :(
   }
}

New situation:

protected class ProtectedClass{
   private INewPublicClass _newPublicClass;

   public ProtectedClass(INewPublicClass newPublicClass) {
      _newPublicClass = newPublicClass;
   }

   protected void ProtectedMethod(){
      //the logic you wanted to test has been moved to another class
      _newPublicClass.DoStuff();
   }
}

public class NewPublicClass : INewPublicClass
{
   public void DoStuff() {
      //this logic can be tested!
   }
}

public class NewPublicClassTest
{
    NewPublicClass _target;
    public void DoStuff_WithoutInput_ShouldSucceed() {
        //Arrange test and call the method with the logic you want to test
        _target.DoStuff();
    }
}
like image 20
nozem Avatar answered Oct 01 '22 06:10

nozem


You can create a stub with a public method that calls the protected method from the base class. This is also how you would use this protected method in production.

public class FooStub : Bar 
{
    public string MyMethodFoo()
    {
        return MyMethodBar();
    }
}

public abstract class Bar 
{
    protected string MyMethodBar()
    {
        return "Hello World!"
    }
}
like image 21
BartKrul Avatar answered Oct 01 '22 06:10

BartKrul