Domanda

Sto provando a Unit Test una classe che ha molte funzioni interne. Anche questi ovviamente hanno bisogno di essere testati, ma il mio progetto Tests è separato, principalmente perché copre molti piccoli progetti correlati. Quello che ho finora è:

FieldInfo[] _fields = 
    typeof(ButtonedForm.TitleButton).GetFields(
        BindingFlags.NonPublic | BindingFlags.Instance | 
        BindingFlags.DeclaredOnly);
Console.WriteLine("{0} fields:", _fields.Length);
foreach (FieldInfo fi in _fields)
{
    Console.WriteLine(fi.Name);
}

Questo sputa bene tutti i membri privati, ma non mostra ancora gli interni. So che questo è possibile, perché quando stavo scherzando con i test generati automaticamente che Visual Studio può produrre, mi chiedeva qualcosa a che fare con la visualizzazione degli interni al progetto Test. Bene, ora sto usando NUnit e mi piace davvero, ma come posso ottenere la stessa cosa con esso?

È stato utile?

Soluzione

Sarebbe più appropriato utilizzare il InternalsVisibleTo per consentire l'accesso ai membri interni dell'assembly all'assemblaggio di test dell'unità.

Ecco un link con alcune utili informazioni aggiuntive e una passeggiata attraverso:

Per rispondere effettivamente alla tua domanda ... Interno e protetto non sono riconosciuti nell'API di Reflection .NET. Ecco una citazione da MSDN :

  

Le parole chiave C # protette e interne non hanno significato in IL e non sono utilizzate nelle API di Reflection. I termini corrispondenti in IL sono Famiglia e Assemblea. Per identificare un metodo interno mediante Reflection, utilizzare IsAssembly proprietà. Per identificare un metodo interno protetto, utilizzare IsFamilyOrAssembly .

Altri suggerimenti

Aggiunta dell'attributo InternalsVisibleTo al progetto principale, con il nome dell'Assemblea del progetto di test dovrebbe rendere visibili i membri interni.

Ad esempio aggiungi quanto segue al tuo assembly al di fuori di qualsiasi classe:

[assembly: InternalsVisibleTo("AssemblyB")]

O per un targeting più specifico:

[assembly:InternalsVisibleTo("AssemblyB, PublicKey=32ab4ba45e0a69a1")]

Nota, se l'assembly dell'applicazione ha un nome sicuro, anche l'assembly di test dovrà essere fortemente denominato.

Penso che dovresti chiederti se dovresti scrivere unit test per metodi privati? Se scrivi test unitari per i tuoi metodi pubblici, con una copertura del codice "ragionevole", non stai già testando metodi privati ??che devono essere chiamati di conseguenza?

Associare i test a metodi privati ??renderà i test più fragili. Dovresti essere in grado di modificare l'implementazione di qualsiasi metodo privato senza interrompere alcun test.

Refs:

http://weblogs.asp.net/tgraham/ archive / 2003/12/31 / 46984.aspx http://richardsbraindump.blogspot.com/2008 /08/should-i-unit-test-private-methods.html http://junit.sourceforge.net/doc/faq/faq.htm#tests_11 http://geekswithblogs.net/geekusconlivus/archive/2006/07/13 /85088.aspx

Il tuo codice mostra solo i campi, quindi spero che non mostrerà alcun membro interno, poiché i campi dovrebbero sempre essere IMO privati. (Con la potenziale eccezione delle costanti.)

ButtonedForm.TitleButton ha effettivamente dei campi non privati? Se stai cercando di trovare metodi interni, ovviamente devi chiamare GetMethods (o GetMembers ) per raggiungerli.

Come altri hanno suggerito, InternalsVisibleTo è molto utile per i test (e quasi esclusivamente per i test!). Per quanto riguarda se dovresti testare metodi interni - certamente trovo utile essere in grado di farlo. Non considero i test unitari come test esclusivamente in scatola nera. Spesso quando sai che la funzionalità pubblica è implementata usando alcuni metodi interni collegati in modo semplice, è più facile fare test approfonditi su ciascuno dei metodi interni e alcuni "pseudointegrazione". test sul metodo pubblico.

Una giustificazione per l'utilizzo di InternalsVisible è nelle mie circostanze. Acquistiamo il codice sorgente su un controllo grafico. Abbiamo scoperto dove dobbiamo apportare alcune modifiche al controllo del codice sorgente e compilare la nostra versione. Ora, per essere sicuri di non aver interrotto nulla, ci sono alcuni test unitari che devo scrivere che richiedono l'accesso ad alcuni campi interni.

Questo è un caso perfetto in cui InternalsVisible ha un senso.

Mi chiedevo, però, cosa fai se non hai accesso alla fonte? Come hai potuto arrivare in un campo interno? .Net Reflector può vedere quel codice, ma immagino che stia solo guardando l'IL.

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