2008-09-16 28 views
6

Uno dei maggiori problemi che mi stanno trattenendo dall'immersione totale ai test di unità è che una percentuale molto elevata del codice che scrivo dipende in larga misura da oggetti COM di terze parti provenienti da fonti diverse che tendono anche a interagire tra loro (Sto scrivendo componenti aggiuntivi per Microsoft Office utilizzando diverse librerie di supporto, se hai bisogno di sapere).Come si esegue il test del codice dell'unità con cui interagisce e si creano istanze di oggetti COM di terze parti?

So che probabilmente dovrei usare gli oggetti finti, ma come fare esattamente in questo caso? Riesco a vedere che è relativamente facile quando devo passare un riferimento a un oggetto già esistente ma alcune delle mie routine creano istanze di oggetti COM esterni e talvolta le passano a qualche altro oggetto COM esterno da una libreria diversa.

Qual è l'approccio migliore? Dovrei avere il mio codice di test per modificare temporaneamente le informazioni di registrazione COM nel registro in modo che il codice testato istanzia invece uno dei miei oggetti mock? Devo inserire unità di libreria di tipo modificato? Quali altri approcci ci sono?

Sarei particolarmente grato per esempi o strumenti per Delphi, ma sarei altrettanto felice con consigli più generali e spiegazioni di livello superiore altrettanto bene.

Grazie,

Oliver

risposta

6

L'approccio tradizionale afferma che il codice client deve utilizzare un wrapper, che è responsabile per istanziare l'oggetto COM. Questo wrapper può essere facilmente deriso.

Poiché si dispone di parti del codice che istanziano direttamente gli oggetti COM, questo non si adatta perfettamente. Se è possibile modificare tale codice, è possibile utilizzare il modello di fabbrica: utilizzano la fabbrica per creare l'oggetto COM. Puoi prendere in giro la fabbrica per restituire oggetti alternativi.

A prescindere dal fatto che l'accesso a un oggetto avvenga tramite un wrapper o tramite l'interfaccia COM originale. Se scegli di simulare l'interfaccia COM, ricorda di utilizzare lo strumento IUnknown :: QueryInterface nella tua simulazione, in modo da sapere che hai deriso tutte le interfacce, in particolare se l'oggetto è passato a qualche altro oggetto COM.

In alternativa, controllare il metodo CoTreateAsClass. Non l'ho mai usato, ma potrebbe fare quello che ti serve.

3

Si tratta di 'progettazione per testabilità'. Idealmente, non dovresti istanziare direttamente quegli oggetti COM, ma dovresti accedervi attraverso uno strato di riferimento indiretto che può essere sostituito da un oggetto fittizio.

Ora, la COM stessa fornisce un livello di riferimento indiretto e potresti fornire un oggetto fittizio che fornisce un sostituto per quello reale ma sospetto che sarebbe un problema creare e dubito che tu possa ottenere molto aiuto da un quadro di derisione esistente.

+0

concordato; e dal momento che tutte le interazioni con gli oggetti COM (ad eccezione delle chiamate di automazione tramite IDispatch) utilizzano un'interfaccia COM, dovresti essere in grado di implementare quelli nella tua classe di simulazione. – rpetrich

2

Scriverei una classe di wrapper sottile attorno all'oggetto COM di terze parti, che ha la capacità di caricare un oggetto fittizio anziché l'oggetto COM effettivo nella situazione di test dell'unità. Normalmente lo faccio avendo un secondo costruttore che chiamo passando nell'oggetto mock. Il costruttore normale avrebbe appena caricato l'oggetto COM come normale.

L'articolo di Wikipedia ha una buona introduzione al tema Wikipedia artible