Test de métodos privados. PrivateObject

Cuando realizamos test unitarios, en principio solo podemos realizar test de los métodos públicos. Pero es habitual querer realizar test de métodos privados, Visual Studio permite crear clases de acceso, denominadas “accesors”, estas clases se generar automáticamente cuando seleccionamos la opción de “generar test” desde el menú contextual del editor de código, pero es un sistema poco intuitivo que personalmente no me gusta nada. Además en VisualStudio 2012 la opción de generar los test automáticamente esta bastante escondida …http://dl.my/2013/enable-create-unit-tests-on-visual-studio-2012/ .

Otra forma mas elegante e intuitiva (a mi juicio) es utilizar la clase PrivateObject que nos permite ejecutar métodos privados y poder testearlos.

Veamos un ejemplo. Supongamos la siguiente clase, Foo. La clase tiene un única método público, que a partir de un array de cadenas de texto, devuelve un nuevo array con los tres primeros caracteres del texto de entrada. No es nada complejo, pero así salimos un poco del clásico ejemplo de la calculadora que utiliza todo el mundo cuando habla de testing… 

La clase es la siguiente:

public class Foo
{
    private string[] names;
    public Foo(string[] names)
    {
        this.names = names;
    }

    public string[] GetShortNames()
    {
        List<String> returnValue = new List<string>(names.Length);

        foreach (var name in names)
        {
            returnValue.Add(GetShortName(name));
        }
        return returnValue.ToArray();
    }

    private string GetShortName(string name)
    {
        return name.Length > 3 ? name.Substring(0, 3) : name;
    }
}

Como podemos ver, el método público GetShortNames utiliza un método privado GetShortName. Por supuesto que testeando el método público estamos testeando también el privado, pero es mejor testear ambos, entre otras ventajas, si algo falla nos permitirá determinar más fácilmente donde esta el error. Además si aplicamos TDD es imprescindible.

Ahora vamos a ver el ejemplo del test del método privado. Por supuesto necesitamos agregar un nuevo proyecto de test a nuestra solucion, y agragar una clase FooTest como la siguiente:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ConsoleApplication1.UnitTest
{
    [TestClass]
    public class FooTest
    {
        // SUT: Foo

        [TestMethod]
        public void GetShortNameTest()
        {
            // arrange
            var foo = new Foo(new string[0]);
            var privateObject = new PrivateObject(foo, new PrivateType(typeof (Foo)));
            var name = "www.devjoker.com";
            
            // act
            var actual = privateObject.Invoke("GetShortName", name);

            // assert
            Assert.AreEqual(actual, "www");
        }
    }
}

Como podemos ver, creamos una instancia de la clase Foo, y la utilizamos para crear un objeto PrivateObject con el que invocamos al método privado. Al ejecutar el test podemos ver que se ejecuta el método privado, que es lo que pretendíamos.

image

Saludos,

DJK

Pedro  Herrarte  Sánchez
Test de métodos privados. PrivateObject
Pedro Herrarte Sánchez

Pedro Herrarte, es consultor independiente, ofreciendo servicios de consultoría, análisis, desarrollo y formación. Posee mas de diez años de experiencia trabajando para las principales empresas de España. Es especialista en tecnologías .NET, entornos Web (ASP.NET, ASP.NET MVC,jQuery, HTML5), bases de datos (SQL Server y ORACLE) e integración de sistemas. Es experto en desarrollo (C#, VB.Net, T-SQL, PL/SQL, , ASP, CGI , C, Pro*C, Java, Essbase, Vignette, PowerBuilder y Visual Basic ...) y bases de datos (SQL Server y ORACLE). Pedro es MCP y MAP 2012, es fundador, diseñador y programador de www.devjoker.com..
Fecha de alta:30/05/2013
Última actualizacion:31/05/2013
Visitas totales:4698
Valorar el contenido:
Últimas consultas realizadas en los foros
Últimas preguntas sin contestar en los foros de devjoker.com