Generazione del codice, compilazione e convenzioni di denominazione in Microsoft Fakes
In questo argomento vengono descritte le opzioni e i problemi di falsificazione nella generazione e compilazione di codice. Descrive le convenzioni di falsificazione nella denominazione per i tipi generati, i membri e i parametri.
Requisiti
- Visual Studio Ultimate •
In questo argomento
Generazione di codice e compilazione
- Generazione di codice di configurazione degli stub • Filtro dei tipi • Generare stub per classi concrete e metodi virtuali • Tipi interni • Ottimizzazione dei tempi di compilazione • Evitare di provocare conflitti di nome assembly
Convenzioni di denominazione delle falsificazioni
- Convenzioni di denominazione dei tipi di shim e di stub • Convenzioni di denominazione della proprietà delegata dello shim o del campo delegato dello stub • Convenzioni di denominazione dei tipi di parametro • Regole ricorsive
Risorse esterne
- Linee guida
Generazione di codice e compilazione
Generazione di codice di configurazione degli stub
La generazione dei tipi stub è configurata in un file XML con estensione di file .fakes.Il framework di falsificazione è integrato nel processo di compilazione tramite le attività MSBuild personalizzate e rileva tali file in fase di compilazione.Il generatore di codice di falsificazione compila i tipi stub in un assembly e aggiunge il riferimento al progetto.
L'esempio seguente illustra i tipi stub definiti in FileSystem.dll:
<Fakes xmlns="https://schemas.microsoft.com/fakes/2011/">
<Assembly Name="FileSystem"/>
</Fakes>
Filtro del tipo
I filtri possono essere impostati nel file .fakes per limitare i tipi per i quali deve essere generato lo stub.È possibile aggiungere un numero illimitato di Clear, Aggiungi, Rimuovi elementi nell'elemento StubGeneration per compilare l'elenco dei tipi selezionati.
Ad esempio, questo file .fakes genera stub per i tipi negli spazi dei nomi System.IO e System, ma esclude qualsiasi tipo che contiene "Handle" in System:
<Fakes xmlns="https://schemas.microsoft.com/fakes/2011/">
<Assembly Name="mscorlib" />
<!-- user code -->
<StubGeneration>
<Clear />
<Add Namespace="System!" />
<Add Namespace="System.IO!"/>
<Remove TypeName="Handle" />
</StubGeneration>
<!-- /user code -->
</Fakes>
Le stringhe di filtro utilizzano una sintassi semplice per definire come la corrispondenza deve essere eseguita:
i filtri sono senza distinzione tra maiuscole e minuscole per impostazione predefinita; i filtri eseguono una corrispondenza nella sottostringa:
el trova corrispondenza in "hello"
L'aggiunta di ! alla fine del filtro genererà distinzione tra maiuscole e minuscole:
el! non corrisponde a "hello"
hello! trova corrispondenza in "hello"
L'aggiunta di * alla fine del filtro lo farà corrispondere al prefisso della stringa:
el* non corrisponde a "hello"
he* trova corrispondenza in "hello"
Più filtri in un elenco separato da punti e virgola sono combinati come OR:
el;wo corrisponde a "hello"e "world"
Generare stub per classi concrete e metodi virtuali
Per impostazione predefinita, i tipi stub sono generati per tutte le classi unsealed.È possibile limitare i tipi dello stub alle classi astratte tramite il file di configurazione .fakes:
<Fakes xmlns="https://schemas.microsoft.com/fakes/2011/">
<Assembly Name="mscorlib" />
<!-- user code -->
<StubGeneration>
<Types>
<Clear />
<Add AbstractClasses="true"/>
</Types>
</StubGeneration>
<!-- /user code -->
</Fakes>
Tipi interni
Il generatore di codice di falsificazione genererà tipi shim e stub per i tipi visibili dall'assembly di falsificazione generato.Per rendere i tipi interni di un assembly reso shim, visibile all'assembly di test e fake, aggiungere attributi InternalsVisibleToAttribute al codice di assembly reso shim che fornisce la visibilità all'assembly di fake generato e all'assembly di test.Di seguito è riportato un esempio:
// FileSystem\AssemblyInfo.cs
[assembly: InternalsVisibleTo("FileSystem.Fakes")]
[assembly: InternalsVisibleTo("FileSystem.Tests")]
Tipi interni in assembly con nome sicuro
Se l'assembly sottoposto a shim è dotato di un nome sicuro e si desidera accedere ai tipi interni dell'assembly:
Sia l'assembly di test che l'assembly di falsificazioni devono avere un nome sicuro.
È necessario aggiungere chiavi pubbliche del test e dell'assembly di Fake agli attributi InternalsVisibleToAttribute in assembly resi shim.Di seguito è riportato l'aspetto degli attributi di esempio nel codice dell'assembly sottoposto a shim quando quest'ultimo è dotato di un nome sicuro:
// FileSystem\AssemblyInfo.cs [assembly: InternalsVisibleTo("FileSystem.Fakes", PublicKey=<Fakes_assembly_public_key>)] [assembly: InternalsVisibleTo("FileSystem.Tests", PublicKey=<Test_assembly_public_key>)]
Se l'assembly sottoposto a shim ha un nome sicuro, il framework Fakes firmerà in modo automatico il codice generato da Fakes.È necessaria una firma sicura dell'assembly di test.Vedere Creazione e utilizzo degli assembly con nome sicuro.
Il framework Fakes utilizza la stessa chiave per firmare tutti gli assembly generati, pertanto è possibile utilizzare il frammento come punto di partenza per aggiungere l'attributo InternalsVisibleTo per l'assembly Fakes al codice dell'assembly reso shim.
[assembly: InternalsVisibleTo("FileSystem.Fakes, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e92decb949446f688ab9f6973436c535bf50acd1fd580495aae3f875aa4e4f663ca77908c63b7f0996977cb98fcfdb35e05aa2c842002703cad835473caac5ef14107e3a7fae01120a96558785f48319f66daabc862872b2c53f5ac11fa335c0165e202b4c011334c7bc8f4c4e570cf255190f4e3e2cbc9137ca57cb687947bc")]
È possibile specificare una chiave pubblica diverso per l'assembly di Fake, ad esempio una chiave creata per l'assembly reso shim, specificando il percorso completo del .snk file contenente la chiave alternativa come KeyFile valore dell'attributo nell'Fakes\Compilationelemento del .fakes file.Ad esempio:
<-- FileSystem.Fakes.fakes -->
<Fakes ...>
<Compilation KeyFile="full_path_to_the_alternate_snk_file" />
</Fakes>
È quindi necessario utilizzare la chiave pubblica del file alternativo .snk come secondo parametro dell'attributo InternalVisibleTo per l'assembly Fakes nel codice assembly reso shim:
// FileSystem\AssemblyInfo.cs
[assembly: InternalsVisibleTo("FileSystem.Fakes",
PublicKey=<Alternate_public_key>)]
[assembly: InternalsVisibleTo("FileSystem.Tests",
PublicKey=<Test_assembly_public_key>)]
Nell'esempio precedente i valori Alternate_public_key e Test_assembly_public_key possono essere uguali.
Ottimizzazione dei tempi di compilazione
La compilazione degli assembly di falsificazioni può aumentare notevolmente la fase di compilazione.È possibile ridurre il tempo di compilazione generando gli assembly di falsificazione per gli assembly di sistema .NET e gli assembly di terze parti in un progetto decentralizzato.Poiché tali assembly cambiano raramente nel computer, è possibile utilizzare gli assembly di falsificazione generati in altri progetti.
Dai progetti di unit test, è possibile eseguire semplicemente un riferimento agli assembly di falsificazione compilati ed inseriti nel FakesAssemblies nella cartella del progetto.
Creare una nuova libreria di classi con la versione del runtime :NET che corrisponde ai propri progetti di test.Che verrà denominata Fakes.Prebuild.Rimuovere il file class1.cs nel progetto che non necessario.
Aggiungere il riferimento a tutti gli assembly di terze parti e di sistema per i quali sono necessarie le falsificazioni.
Aggiungere un file .fakes per ogni assembly e compilazione.
Dal proprio progetto di test
Assicurarsi di disporre di un riferimento alla DLL di runtime Fakes:
C:\Programmi\Microsoft Visual Studio 12.0\Common7\IDE\PublicAssemblies\Microsoft.QualityTools.Testing.Fakes.dll
Per ogni assembly per cui sono stati creati Fake, aggiungere un riferimento al file DLL corrispondente nella cartella Fakes.Prebuild\FakesAssemblies del progetto.
Evitare di provocare conflitti di nome assembly
In un ambiente di compilazione Team, tutti gli output di compilazione vengono sottoposti al merge in una singola directory.Nel caso in cui più progetti utilizzino le falsificazioni, può accadere che gli assembly di falsificazione di una versione eseguano l'override su un'altra versione.Ad esempio, le falsificazioni del TestProject1 mscorlib.dll dal .NET Framework 2.0 e TestProject2 mscorlib.dll per il .NET Framework 4 chiamerebbero entrambe l'assembly di falsificazione di mscorlib.Fakes.dll.
Per evitare questo problema, le falsificazioni devono creare automaticamente versioni con i nomi di assembly di falsificazioni qualificati per i riferimenti che non sono di progetto quando vengono aggiunti i file .fakes.Un nome assembly di falsificazioni qualificato con la versione include un numero di versione quando si crea il nome dell'assembly di falsificazione:
Dato un assembly MyAssembly e una versione 1.2.3.4, il nome dell'assembly di falsificazioni è MyAssembly.1.2.3.4.Fakes.
È possibile modificare o rimuovere questa versione modificando l'attributo di versione dell'elemento dell'assembly in .fakes:
attribute of the Assembly element in the .fakes:
<Fakes ...>
<Assembly Name="MyAssembly" Version="1.2.3.4" />
...
</Fakes>
Convenzioni di denominazione delle falsificazioni
Convenzioni di denominazione per tipi resi shim e tipi stub
Spazi dei nomi
Il suffisso .Fakes viene aggiunto allo spazio dei nomi.
Ad esempio, lo spazio dei nomi System.Fakes contiene i tipi lo spessore di spazi dei nomi system.
Global.Fakes contiene il tipo lo spessore dello spazio dei nomi vuoto.
Nomi dei tipi
Un prefisso reso shim è aggiunto al nome del tipo per creare il nome del tipo reso shim.
Per esempio, ShimExample è un tipo reso shim del tipo Example.
Il prefisso stub viene aggiunto al nome del tipo per compilare il nome del tipo stub.
Ad esempio, StubIExample è il tipo dello stub del tipo IExample.
Argomenti di tipo e strutture di tipo annidato
Gli argomenti di tipo generico vengono copiati.
Una struttura di tipo annidato viene copiata per i tipi resi shim.
Convenzioni di denominazione per proprietà delegate rese shim o campi stub delegati
Regole di base per il campo di denominazione, a partire da un nome vuoto:
Il nome del metodo è aggiunto.
Se il nome del metodo è un'implementazione di interfaccia esplicita, i punti vengono rimossi.
Se il metodo è generico, Ofn viene aggiunto dove n è il numero di argomenti generici del metodo.
Nomi speciali dei metodi come il metodo Get o Set per una proprietà vengono considerati come descritti nella tabella seguente.
Se il metodo è… |
Esempio |
Nome del metodo aggiunto |
---|---|---|
Un costruttore |
.ctor |
Constructor |
Un costruttore statico |
.cctor |
StaticConstructor |
Una funzione di accesso con il nome del metodo costituito da due parti separate da "_" (come i metodi Get delle proprietà) |
kind_name (caso comune, ma non applicato da ECMA) |
NameKind, dove entrambe le parti sono state scritte con il maiuscolo e scambiate |
Metodo Get della proprietà Prop |
PropGet |
|
Metodo set della proprietà Prop |
PropSet |
|
Addizionatore di evento |
Add |
|
Rimozione dell'evento |
Remove |
|
Un operatore costituito da due parti |
op_name |
NameOp |
Ad esempio: operatore + |
op_Add |
AddOp |
Per un operatore di conversione, il tipo restituito è aggiunto. |
T op_Implicit |
ImplicitOpT |
Note
Metodi Get e Set per gli indicizzatori vengono considerati analogamente alla proprietà.Il nome predefinito per un indicizzatore è Item.
I nomi del tipo di parametro vengono modificati e concatenati.
Il tipo restituito viene ignorato a meno che non ci sia ambiguità di overload.In questo caso, il tipo restituito viene aggiunto alla fine del nome
Convenzioni di denominazione del tipo di parametro
Dato |
La stringa aggiunta è… |
---|---|
Un tipo T |
T Lo spazio dei nomi, la struttura annidata e i tic generici vengono eliminati. |
Un parametro outout T |
TOut |
Un parametro ref ref T |
TRef |
Un tipo arrayT[] |
TArray |
Un tipo array multi-dimensionaleT[ , , ] |
T3 |
Un tipo puntatore, T* |
TPtr |
Un tipo generico T<R1, …> |
TOfR1 |
Un argomento di tipo generico!i di tipo C<TType> |
Ti |
Un argomento generico del metodo!!i del metodo M<MMethod> |
Mi |
Un tipo annidatoN.T |
N viene aggiunta, dopo T |
Regole ricorsive
Le regole seguenti sono applicate in modo ricorsivo:
Poiché Fakes utilizza C# per generare assembly Fakes, qualsiasi carattere che produce un token C# non valido viene sostituito da "_" (underscore).
Se un nome risultante non è compatibile con nessun membro del tipo dichiarante, una combinazione di numerazione viene utilizzata aggiungendo un contatore a due cifre, partendo da 01.