2010-06-14 10 views
6

Ho un assembly .NET, da rilasciare. La sua build di rilascio comprende:Nascondi metodo pubblico utilizzato per testare un assembly .NET

  • A, API documentata pubblica di metodi che la gente si suppone di utilizzare
  • un'API pubblica, ma non documentata di altri metodi, che esistono solo al fine di aiutare a testare l'assemblaggio, e che la gente non dovrebbero usare

L'assembly da rilasciare è un controllo personalizzato, non un'applicazione. Per eseguire il test di regressione, lo eseguo in un framework/applicazione di test, che utilizza (oltre all'API pubblica/documentata) alcuni metodi avanzati/non documentati che vengono esportati dal controllo.

Per i metodi pubblici che non voglio persone di utilizzare, li escluso dalla documentazione utilizzando la <exclude> tag (supportato dal Costruttore Sandcastle File della Guida), e l'attributo [EditorBrowsable], per esempio come questo:

/// <summary> 
/// Gets a <see cref="IEditorTransaction"/> instance, which helps 
/// to combine several DOM edits into a single transaction, which 
/// can be undone and redone as if they were a single, atomic operation. 
/// </summary> 
/// <returns>A <see cref="IEditorTransaction"/> instance.</returns> 
IEditorTransaction createEditorTransaction(); 

/// <exclude/> 
[EditorBrowsable(EditorBrowsableState.Never)] 
void debugDumpBlocks(TextWriter output); 

Questo rimuove con successo il metodo dalla documentazione API e da Intellisense. Tuttavia, se in un programma applicativo di esempio right-click su un'istanza dell'interfaccia di vedere la definizione nel metadati, posso ancora vedere il metodo e il [EditorBrowsable] attributo così, ad esempio:

// Summary: 
//  Gets a ModelText.ModelDom.Nodes.IEditorTransaction instance, which helps 
//  to combine several DOM edits into a single transaction, which can be undone 
//  and redone as if they were a single, atomic operation. 
// 
// Returns: 
//  A ModelText.ModelDom.Nodes.IEditorTransaction instance. 
IEditorTransaction createEditorTransaction(); 
// 
[EditorBrowsable(EditorBrowsableState.Never)] 
void debugDumpBlocks(TextWriter output); 

Domande:

  • c'è un modo per nascondere un metodo pubblico, anche da metadati?
  • In caso contrario, per questo scenario, si consiglia di eseguire i metodi internal e utilizzare l'attributo InternalsVisibleTo? O consiglieresti un altro modo, e se sì, cosa e perché?

Grazie.

+5

Suggerirei una progettazione adeguata che non richieda di esporre pubblicamente il codice che preferiresti nascondere. –

+0

Concordato con Mark. Dovresti essere in grado di testare tutto il tuo codice attraverso le sue interfacce pubbliche senza dover creare metodi pubblici e/o interni "nascosti". –

+0

@ Mark I am [test del codice tramite interfacce pubbliche] (http://stackoverflow.com/questions/856115), tuttavia per aiutare il test di regressione ho alcuni metodi aggiuntivi, ad es. che esegue il dump dello stato interno del controllo: in modo che il test case possa affermare lo stato interno (non documentato) dopo vari eventi di input (pubblici, documentati). – ChrisW

risposta

0

Le due possibilità sono InternalsVisibleTo e/o riflessione. Non sono a conoscenza di alcun motivo valido per preferire uno sopra l'idea.

6

internal/InternalsVisibleTo è un buon approccio, ma genera ancora i metodi nel codice compilato e saranno disponibili tramite la riflessione.

È sempre possibile utilizzare un simbolo di compilazione condizionale per il test dell'unità che aggiunge solo i metodi di prova e, quando si crea la versione di rilascio, non lo definisce. In questo modo, i metodi semplicemente non esistono se non sono incorporati nella configurazione "Test".

+0

+1 simboli usati come questo in passato, di gran lunga il modo più semplice per andare. –

+0

Non mi importa degli hacker che usano la riflessione; Semplicemente non voglio che i normali consumatori del controllo vedano metodi non documentati. Inoltre, la compilazione condizionale non funzionerebbe perché io [testare la versione di rilascio] (http://stackoverflow.com/questions/420343). – ChrisW

+0

Se si crea un'altra configurazione che differisce solo dalla versione di rilascio con i metodi aggiuntivi, finisce per essere la stessa. Non è necessario essere in configurazione di debug per definire altri simboli. – CMerat

0

Personalmente userei lo switch del compilatore, ma potreste sempre usare il reflection nel codice di test dell'unità per arrivare ai membri privati.

+0

Dato che non userò la compilazione condizionale perché voglio [testare la build di rilascio] (http://stackoverflow.com/questions/420343), sai se sarebbe meglio usare il reflection, o usare il ' Attributo InternalsVisibleTo'? – ChrisW

+0

Se le uniche differenze tra le due versioni di codice saranno la firma di un metodo che passa da privato a pubblico, direi che ciò non influisce sulla copertura del test abbastanza da costituire un problema. Se qualcosa si rompe, è molto probabile che il compilatore lo coglierà comunque. Userei il riflesso - è interno e non vuoi che esca così si sistemati. –

Problemi correlati