Come utilizzare AOP da DI Framework con C # TestFrameworks? (NON per l’articolo in prova)

Le mie scuse in anticipo per un titolo terribile – suggerimenti benvenuto!

Ho letto di DI e AOP e penso di cogliere le basi; almeno per l’esempio canonico di aggiunta della registrazione.

Vorrei applicare questo ai casi di test che abbiamo creato in NUnit, ad esempio essere in grado di aggiungere automaticamente la registrazione di entrata / uscita per tutti i metodi di test case e tutti i “metodi di supporto” che chiamano. (E non sono legato a NUnit- se è più semplice in un altro framework, per favore fatemelo sapere.)

NOTA: non si tratta del sobject in esame; Voglio applicare queste tecniche ai testicoli stessi.

È abbastanza chiaro come farlo usando PostSharp – è il loro primo esempio. Comunque non voglio aggiungere la gestione delle loro licenze al nostro progetto solo per questo esperimento.

Tutti gli altri riferimenti che ho trovato su AOP per C # sono basati su Interceptor (dinamici) forniti da implementazioni del contenitore IoC come CastleWindsor, Unity, Spring.Net, … Hanno tutti un problema comune in questo caso: è necessario un pezzo di codice di installazione che crea il proxy per l’object a cui si desidera aggiungere gli interceptor. (All’inizio pensavo che questo codice avrebbe dovuto anche creare un contenitore IoC, ma vedo che mi sbaglio.)

Ma non riesco a vedere dove questo codice di installazione potrebbe andare per i test nUnit.

Le opzioni che ho trovato e i loro problemi:

  1. Avere il costruttore delle classi testfixture crea un proxy per se stesso. Non funzionerà, a causa della ricorsione (il consumatore chiede una cosa, la cosa prova a restituire il proxy alla cosa, il proxy prova a creare qualcosa … leggendo questa domanda StackOverflow )
  2. Rotola la mia magia basata sulla riflessione (che sarebbe una grande impresa per me)
    1. fare in modo che il costruttore avvolga tutti i metodi nella class testfixture e restituisca questo object “avvolto” (non è sicuro se questo è ansible per un costruttore di farlo)
    2. usa un costruttore statico sulla testfixture per fare questa magia (assumendo che tu possa dynamicmente avvolgere i metodi della class in atto).
    3. fare qualcosa a livello di modulo usando un modulo cctor (tramite InjectModuleInitializer di Einar Egilsson ) e avvolgere tutti i metodi in tutte le classi con la registrazione.
  3. Il più semplice: una sorta di factory per l’istanziazione dei testcase (parametri NON per i test), da cui potrei usare uno dei generatori di proxy IoC
    1. Per nUnit: l’unico mezzo che posso trovare per farlo è creare un AddIn personalizzato . Vantaggio: potrebbe non interrompere l’integrazione con ReSharper. Svantaggi: distribuzione su tutte le macchine devs, in particolare sugli aggiornamenti di NUnit. Ci sono altri modi per farlo per nUnit?
    2. Per MbUnit: sembra che consideri i testcase come valori di prima class , e questo è semplice. Vantaggio: facile da implementare per tutti gli sviluppatori. Svantaggio: i test non verranno visualizzati in Resharper. Nota a margine : come gestire il setup e il teardown .

Ho perso qualcosa nelle mie opzioni e conclusioni?

Esistono mezzi più semplici per fare ciò che mi sono perso?

La programmazione orientata all’aspetto non riguarda solo l’utilizzo di proxy dinamici (intercettazione) o la compilazione di codici di compilazione post (PostSharp). AOP riguarda principalmente l’aggiunta di preoccupazioni trasversali. L’utilizzo di proxy dinamici è un modo per aggiungere preoccupazioni trasversali. La tessitura del codice è un altro modo per farlo. Ma c’è un altro, IMO meglio, un modo per aggiungere preoccupazioni trasversali.

Invece di usare i proxy dinamici o la tessitura del codice, lasciati guidare dal design della tua applicazione. Quando progetti la tua applicazione usando le giuste astrazioni, sarebbe facile aggiungere preoccupazioni trasversali ai decoratori. Puoi trovare esempi di sistemi progettati utilizzando astrazioni appropriate qui e qui .

Questi articoli descrivono come definisci le preoccupazioni trasversali che usano i decoratori. Quando hai progettato il sistema in questo modo, puoi testare l’implementazione di un problema trasversale separatamente dal resto del codice. Questo sarà facile quando si usano le astrazioni giuste.

Quando lo fai, non c’è bisogno di fare qualcosa di speciale nei test delle tue unità. Non c’è bisogno di tessere il codice, non è necessario eseguire il contenitore DI nel test per creare oggetti per te. È ansible testare la logica dell’applicazione senza che vi siano problemi trasversali. Puoi testare ogni piccolo pezzo da solo e mettere tutti i pezzi insieme nella Radice di composizione dell’applicazione.