How to test private methods in C#?

Asked

Viewed 967 times

9

How to test private methods using Microsoft.VisualStudio.Testtools.Unittesting and Moq

My test class is like this:

[TestClass]
public class ClasseDeTeste
{

    private  MinhaClasseComMetodosPrivados _minhaClasseComMetodosPrivados;

    [TestInitialize]
    public void Initialize()
    {
        ...inicialização de diversos repositórios 

        _minhaClasseComMetodosPrivados = new MinhaClasseComMetodosPrivados(parametros, ...);
    }

    [TestMethod]
    public void TestarFuncaoPrivadaXXX()
    {

       var result = _minhaClasseComMetodosPrivados.metodoPrivado(param1, param2, param3);

       Assert.AreEqual("retorno esperado ",result);
    }

}
  • Does any of the answers meet the request? Does it need to be improved?

  • In case I think you should accept the LINQ which is what you really wanted to know, mine is complement.

2 answers

9


At first, you shouldn’t test. The idea of unit testing is to test whether the public API is working as expected.

Anyway, it is possible to use the class PrivateObject namespace Microsoft.VisualStudio.TestTools.UnitTesting. It was created precisely for this purpose.

An example of how to use it:

[TestMethod]
public void TestarFuncaoPrivadaXXX()
{       
    var target = new MinhaClasseComMetodosPrivados();       
    var obj = new PrivateObject(target);

    var result = obj.Invoke("MetodoPrivado");

    Assert.AreEqual("retorno esperado ",result);
}

It is also possible to do with Reflection "in hand". Something like:

var target = new MinhaClasseComMetodosPrivados();
var methodInfo = typeof(MinhaClasseComMetodosPrivados).GetMethod("MetodoPrivado", 
                                           BindingFlags.NonPublic | BindingFlags.Instance);

object[] parametros = new [] { 1, "alguma string" }; // Só pra ilustrar
methodInfo.Invoke(target, parametros);

Also, of course, it is possible to create a class wrapper and call private methods through public methods, but this is a very shameless approach.

9

The answer you really want is that of LINQ. But testing unit in private methods is a conceptual error.

Unit tests should verify that the public API is always responding in the expected way. Private methods are implementation details and not part of the public API. Testing them doesn’t make sense because they need to have the freedom to be able to work differently.

The maximum that can be interesting is to have a state invariance check of the object between the execution of private methods. Even this is controversial because there are cases that no matter the invariance in the middle of private processing.

  • You can elaborate on "having a state invariance check of the object ...". In what this (state invariance) can affect the API client

  • @ramaral thinks it’s worth it here? it seems to be a tangential subject and not the focus of the question. I don’t know, if I find I edit here, otherwise it’s better something proper for it.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.