2012-03-16 9 views
13

Dopo aver chiesto a questo question di implementare un aspetto con PostSharp, mi è venuto in mente che potrei dover aggiornare il codice di questo aspetto in futuro, e che non volevo correre il rischio di rompere tutto in seguito.Come testare gli aspetti di PostSharp?

Così, ho iniziato a pensare ai test unitari.

mia prima domanda è:

Se sia rilevante per pensare di test di unità un aspetto?

Vorrei che la risposta fosse "sì", ma in caso contrario, mi aspetto di ricevere altri consigli.

E poi, in caso affermativo,

come implementare test di unità per gli aspetti PostSharp?

risposta

10

Sì, certamente ha senso per gli aspetti dei test unitari, dal momento che rappresentano la funzionalità e dal momento che lo si sta utilizzando in più punti, è ancora più importante verificarlo.

Tuttavia si deve dividere questo in due parti:

  1. testare la funzionalità aspetto attuale
  2. verificare se l'estrazione contesto funziona correttamente che è usato per eseguire effettivamente la funzionalità aspetto

Per la prima parte, se hai disaccoppiato la funzionalità effettiva dall'attributo che esegue correttamente la funzionalità dell'aspetto, la creazione di test unitari non dovrebbe essere diversa dall'unità testando il codice normale.

Per la seconda parte è necessario separare l'estrazione del contesto così, questo potrebbe sembrare eccessivo, ma se si Wanne unit test correttamente avrete bisogno di todo lo temo.

Su questa nota si dovrebbe anche fare ricorso alla convalida del tempo di compilazione, che può anche impedire di utilizzare gli attributi nel modo sbagliato. A volte è necessario testare alcune condizioni che non è possibile descrivere con la sintassi degli attributi, quindi entra in gioco la convalida del tempo di compilazione. Questo è stato un grande vantaggio per me e ridotto la quantità di sessioni di debug per quanto riguarda gli aspetti PostSharp in modo significativo, vedi:
http://www.sharpcrafters.com/postsharp/robustness

Ecco alcuni esempi di codice molto semplice, nessun DI niente, solo per illustrare come dividere le cose up:

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); 
    } 
} 

si potrebbe chiedere perché TraceService e un separato TraceArgumentService:

  • La logica Tracing deve essere indipendente da PostSharp, quindi sho Non potrei sapere di MethodExecutionArgs.
  • L'estrazione degli argomenti da MethodExecutionArgs non fa parte di Traccia, è più correlata all'aspetto. Dal momento che vuoi essere in grado di testarlo, devi in ​​qualche modo separarlo.
+0

Sono pienamente d'accordo con la vostra "prima parte". Riguardo la tua "seconda parte", sto cercando un esempio di codice per capire "come sarebbe" come questo è il punto chiave della mia domanda. Analizzerò la convalida del tempo di compilazione in base al tuo suggerimento. – remio

+1

@remio Ho aggiornato la mia risposta con un esempio di come separare l'attività diversa per renderli verificabili. – ntziolis

+0

Ho capito. Il disaccoppiamento è la chiave. Grazie mille per il tuo esempio esplicito. – remio

Problemi correlati