2012-03-16 5 views
13

Después de preguntar esto question sobre la implementación de un aspecto con PostSharp, me vino a la mente que podría tener que actualizar el código de este aspecto en el futuro, y que no quería correr el riesgo de romper todo después.¿Cómo probar de forma unitaria los aspectos de PostSharp?

Entonces, comencé a pensar en pruebas unitarias.

Mi primera pregunta es:

¿Es relevante para pensar en la unidad de prueba de un aspecto?

Me gustaría que la respuesta sea "sí", pero si no, espero obtener otros consejos.

Y luego, si es así,

la forma de aplicar las pruebas unitarias para los aspectos PostSharp?

Respuesta

10

Sí, ciertamente tiene sentido para los aspectos de las pruebas unitarias, ya que representan la funcionalidad y dado que lo está utilizando en más de un lugar, es aún más importante probarlo.

Sin embargo hay que dividiremos esta en dos partes:

  1. Prueba de la funcionalidad aspecto actual
  2. comprobar que es la extracción de contexto está funcionando adecuadamente que se utiliza para ejecutar efectivamente la funcionalidad aspecto

Para la primera parte, si ha desacoplado la funcionalidad real del atributo que ejecuta la funcionalidad de aspecto correctamente, la creación de pruebas unitarias no debería ser diferente a la unidad que prueba el código normal.

Para la segunda parte necesita desacoplar la extracción de contexto también, esto podría parecer exagerado, pero si quiere probar la unidad adecuadamente, tendrá que hacerlo todo, me temo.

En ese sentido, también debe hacer uso de la validación de tiempo de compilación, que también puede impedir el uso de los atributos de la manera incorrecta. Algunas veces es necesario probar ciertas condiciones que no se pueden describir con la sintaxis de Atributo, entonces la validación del tiempo de compilación entra en juego. Este ha sido un gran activo para mí y la reducción de la cantidad de sesiones de depuración en lo que respecta a los aspectos PostSharp significativamente, ver:
http://www.sharpcrafters.com/postsharp/robustness

Aquí hay un código de ejemplo muy básico, sin DI nada, sólo para ilustrar cómo dividir las cosas arriba:

public sealed class TraceAttribute : OnMethodBoundaryAspect 
{ 
    private readonly string category; 
    private TraceArgumentService argumentService; 
    private TraceService traceService; 

    public string Category { get { return category; } } 

    public TraceAttribute(string category) 
    { 
     this.category = category; 
    } 

    public override void RuntimeInitialize(System.Reflection.MethodBase method) 
    { 
     base.RuntimeInitialize(method); 
     this.argumentService = new TraceArgumentService(); 
     this.traceService = new TraceService(); 
    } 


    public override void OnEntry(MethodExecutionArgs args) 
    {     
     traceService.Write(
      argumentService.GetDeclaringTypeName(args), 
      argumentService.GetMethodName(args), 
      category); 

    } 
} 

public class TraceArgumentService 
{ 
    public string GetDeclaringTypeName(MethodExecutionArgs args) 
    { 
     return args.Method.DeclaringType.Name; 
    } 

    public string GetMethodName(MethodExecutionArgs args) 
    { 
     return args.Method.Name; 
    } 
} 

public class TraceService 
{ 
    public void Write(string declaringTypeName, string methodName, string category) 
    { 
     Trace.WriteLine(string.Format("Entering {0}.{1}.", 
      declaringTypeName, methodName), category); 
    } 
} 

Usted podría preguntarse por qué TraceService y una separada TraceArgumentService:

  • La lógica de rastreo debe ser independiente de PostSharp, por lo tanto, sho uld no se sabe acerca de MethodExecutionArgs.
  • Extraer los argumentos de MethodExecutionArgs no es parte de Tracing, está más relacionado con el aspecto. Como desea poder probarlo, debe separarlo de alguna manera.
+0

estoy totalmente de acuerdo con su "primera parte". Sobre su "segunda parte", estoy buscando una muestra de código para entender "cómo se vería esto" ya que este es el punto clave de mi pregunta. Investigaré la validación del tiempo de compilación de acuerdo con su sugerencia. – remio

+1

@remio He actualizado mi respuesta con una muestra de cómo separar las diferentes tareas para que sean comprobables – ntziolis

+0

Lo entiendo. El desacoplamiento es la clave. Muchas gracias por tu ejemplo explícito. – remio

Cuestiones relacionadas