Come si esegue il test unitario del codice che interagisce con e crea un'istanza di oggetti COM di terze parti?

StackOverflow https://stackoverflow.com/questions/70482

Domanda

Uno dei maggiori problemi che attualmente mi trattiene dal tuffarmi a pieno ritmo nei test unitari è che una percentuale molto elevata del codice che scrivo dipende fortemente da oggetti COM di terze parti provenienti da fonti diverse che tendono anche a interagire tra loro (io' sto scrivendo componenti aggiuntivi per Microsoft Office utilizzando diverse librerie di supporto se è necessario saperlo).

So che probabilmente dovrei usare oggetti finti, ma come potrei farlo esattamente in questo caso?Vedo che è relativamente semplice quando devo solo passare un riferimento a un oggetto già esistente, ma alcune delle mie routine istanziano essi stessi oggetti COM esterni e poi a volte li passano a qualche altro oggetto COM esterno da una libreria ancora diversa.

Qual è l’approccio migliore in questo caso?Dovrei fare in modo che il mio codice di test modifichi temporaneamente le informazioni di registrazione COM nel registro in modo che il codice testato crei invece un'istanza di uno dei miei oggetti fittizi?Dovrei iniettare unità di libreria dei tipi modificate?Quali altri approcci esistono?

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

Grazie,

Oliver

È stato utile?

Soluzione

L'approccio tradizionale prevede che il codice client utilizzi un wrapper, responsabile della creazione di un'istanza dell'oggetto COM.Questo involucro può quindi essere facilmente deriso.

Poiché hai parti del tuo codice che istanziano direttamente gli oggetti COM, questo non si adatta perfettamente.Se puoi modificare quel codice, puoi utilizzare il modello di fabbrica:usano la factory per creare l'oggetto COM.Puoi deridere la fabbrica per restituire oggetti alternativi.

Dipende da te se si accede all'oggetto tramite un wrapper o tramite l'interfaccia COM originale.Se scegli di simulare l'interfaccia COM, ricorda di inserire IUnknown::QueryInterface nel tuo mock, così saprai di aver deriso tutte le interfacce, in particolare se l'oggetto viene poi passato a qualche altro oggetto COM.

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

Altri suggerimenti

Si tratta di "progettare per la testabilità".Idealmente, non dovresti creare un'istanza di questi oggetti COM direttamente ma dovresti accedervi attraverso un livello di riferimento indiretto che può essere sostituito da un oggetto fittizio.

Ora, COM stesso fornisce un livello di riferimento indiretto e potresti fornire un oggetto fittizio che fornisca un sostituto per quello reale, ma sospetto che sarebbe una seccatura crearlo e dubito che otterresti molto aiuto da un framework beffardo esistente .

Vorrei scrivere una classe 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 unitario.Normalmente lo faccio avendo un secondo costruttore che chiamo passaggio nell'oggetto mock.Il costruttore normale avrebbe semplicemente caricato l'oggetto COM normalmente.

L'articolo di Wikipedia ha una buona introduzione all'argomentoArticolo di Wikipedia

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top