Partager via


Génération et compilation de code et conventions d'affectation de noms dans Microsoft Fakes

Cette rubrique traite des options et des problèmes dans la génération et la compilation de code Fakes, et décrit les conventions d'affectation de noms pour les types Fakes générés, les membres et les paramètres.

Configuration requise

  • Visual Studio Ultimate •

Dans cette rubrique

Génération de code et compilation

  • Configuration de la génération du code de stubs • Filtrage de types • Classes concrètes d'opération stub et méthodes virtuelles • Types internes • Optimisation des durées de build • Comment éviter les conflits de noms d'assembly

Fausses conventions d'affectation de noms

  • Conventions de nommage du type shim et du type stub • Conventions de nommage de la propriété déléguée shim ou du champ délégué stub • Conventions d'affectation de nom de type de paramètre • Règles récursives

Ressources externes

  • Aide

Génération de code et compilation

Configuration de la génération du code des stubs

La génération de types stub est configurée dans un fichier XML avec l'extension de fichier .fakes.L'infrastructure Fakes s'intègre au processus de génération via des tâches personnalisées MSBuild et détecte ces fichiers au moment de la génération.Le générateur de code Fakes compile les types de stub dans un assembly et ajoute la référence au projet.

L'exemple suivant montre des types de stub définis dans FileSystem.dll :

<Fakes xmlns="https://schemas.microsoft.com/fakes/2011/">
    <Assembly Name="FileSystem"/>
</Fakes>

Filtrage de types

Les filtres peuvent être définis dans le fichier .fakes pour restreindre les types à extraire.Vous pouvez ajouter un nombre illimité d'éléments Clear, Add, Remove sous l'élément StubGeneration pour générer la liste des types sélectionnés.

Par exemple, ce fichier .fakes génère des stubs pour les types sous les espaces de noms System et System.IO, mais exclut tout type qui contient « Handle » dans 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>

Les chaînes de filtre utilisent une syntaxe simple pour définir comment la correspondance doit être effectuée :

  • Les filtres ne sont pas sensibles à la casse par défaut ; les filtres effectuent une correspondance de sous-chaîne :

    el correspond à « hello »

  • L'ajout de ! à la fin du filtre en fera une correspondance rigoureusement sensible à la casse :

    el! ne correspond pas à « hello »

    hello! correspond à « hello »

  • Ajouter * à la fin du filtre le fera correspondre au préfixe de la chaîne :

    el* ne correspond pas à « hello »

    he* correspond à « hello »

  • Plusieurs filtres dans une liste délimitée par des points-virgules sont combinés comme une disjonction :

    el;wo correspond à « hello » et « world »

Classes concrètes et méthodes virtuelles d'opérations stub

Par défaut, les types stub sont générés pour toutes les classes non-sealed.Il est possible de restreindre les types de stub aux classes abstraites dans le fichier de configuration .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>

Types internes

Le générateur de code Fakes génère des types shim et stub pour les types qui sont visibles de l'assembly généré Fakes.Pour que les types internes d'un assembly ayant fait l'objet d'un shim soient visibles à l'assembly Fakes et à votre assembly de test, ajoutez les attributs InternalsVisibleToAttribute au code de l'assembly ayant fait l'objet d'un shim qui donne de la visibilité à l'assembly Fakes généré et à l'assembly de test.Voici un exemple :

// FileSystem\AssemblyInfo.cs
[assembly: InternalsVisibleTo("FileSystem.Fakes")]
[assembly: InternalsVisibleTo("FileSystem.Tests")]

Interne dans les assemblys à nom fort

Si l'assembly calé porte un nom fort et que vous souhaitez des types internes d'accès des assemblys :

  • Votre assembly de test comme l'assembly de faux doivent être fortement nommés.

  • Vous devez ajouter les clés publiques de l'assembly de test et Fakes aux attributs InternalsVisibleToAttribute des assemblys ayant fait l'objet d'un shim.Voici l'apparence de nos attributs d'exemple dans le code d'assembly calé lorsque l'assembly calé porte un nom fort :

    // FileSystem\AssemblyInfo.cs
    [assembly: InternalsVisibleTo("FileSystem.Fakes",
        PublicKey=<Fakes_assembly_public_key>)]
    [assembly: InternalsVisibleTo("FileSystem.Tests",
        PublicKey=<Test_assembly_public_key>)]
    

Si l'assembly qui fait l'objet d'un shim est fortement nommé, l'infrastructure Fakes signe automatiquement fortement l'assembly Fakes généré.Vous devez signer avec un nom fort l'assembly de test.Consultez Création et utilisation d'assemblys avec nom fort.

L'infrastructure Fakes utilise la même clé pour signer tous les assemblys générés. Par conséquent, vous pouvez utiliser cet extrait de code comme point de départ pour ajouter l'attribut InternalsVisibleTo de l'assembly Fakes à votre code assembleur ayant fait l'objet d'un shim.

[assembly: InternalsVisibleTo("FileSystem.Fakes, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e92decb949446f688ab9f6973436c535bf50acd1fd580495aae3f875aa4e4f663ca77908c63b7f0996977cb98fcfdb35e05aa2c842002703cad835473caac5ef14107e3a7fae01120a96558785f48319f66daabc862872b2c53f5ac11fa335c0165e202b4c011334c7bc8f4c4e570cf255190f4e3e2cbc9137ca57cb687947bc")]

Vous pouvez spécifier une autre clé publique pour l'assembly Fakes, par exemple une clé que vous avez créée pour l'assembly ayant fait l'objet d'un shim, en spécifiant le chemin d'accès complet au fichier .snk qui contient l'autre clé comme valeur d'attribut KeyFile dans l'élément Fakes\Compilation du fichier .fakes.Par exemple :

<-- FileSystem.Fakes.fakes -->
<Fakes ...>
  <Compilation KeyFile="full_path_to_the_alternate_snk_file" />
</Fakes>

Vous devez ensuite utiliser la clé publique de l'autre fichier .snk comme second paramètre de l'attribut InternalVisibleTo pour l'assembly Fakes dans le code d'assembly ayant fait l'objet d'un shim :

// FileSystem\AssemblyInfo.cs
[assembly: InternalsVisibleTo("FileSystem.Fakes",
    PublicKey=<Alternate_public_key>)]
[assembly: InternalsVisibleTo("FileSystem.Tests",
    PublicKey=<Test_assembly_public_key>)]

Dans l'exemple ci-dessus, les valeurs Alternate_public_key et Test_assembly_public_key peuvent être identiques.

Optimiser la durée de la génération

La compilation des assemblys Fakes peut augmenter considérablement la durée de la génération.Vous pouvez réduire la durée de la génération en générant de faux assemblys pour les assemblys système .NET et des assemblys tiers dans un projet central séparé.Comme ce genre d'assembly change rarement sur votre ordinateur, vous pouvez réutiliser les assemblys Fakes générés dans d'autres projets.

Depuis vos projets de test unitaire, vous pouvez simplement prendre une référence aux assemblys Fakes compilés qui sont placés sous le FakesAssemblies dans le dossier du projet.

  1. Créer une nouvelle bibliothèque de classes avec la version du runtime .NET. correspondant à vos projets de test.Appelons-la Fakes.Prebuild.Supprimez le fichier class1.cs du projet, non nécessaire.

  2. Ajoutez la référence à tous les assemblys système et tiers pour lesquels vous avez besoin de Fakes.

  3. Ajoutez un fichier .fakes pour chacun des assemblys et générez.

  4. Depuis votre projet de test

    • Vérifiez que vous avez une référence à la DLL du runtime de faux :

      C:\Program Files\Microsoft Visual Studio 12.0\Common7\IDE\PublicAssemblies\Microsoft.QualityTools.Testing.Fakes.dll

    • Pour chaque assembly pour lequel vous avez créé un faux, ajoutez une référence au fichier DLL correspondant dans le dossier Fakes.Prebuild\FakesAssemblies de votre projet.

Prévention du conflit de nom d'assembly

Dans un environnement Team Build, toutes les sorties de génération sont fusionnées dans un seul répertoire.Dans le cas de plusieurs projets utilisant Fakes, il peut arriver que les assemblys Fakes de versions différentes se substituent.Par exemple, TestProject1 fakes mscorlib.dll depuis le .NET Framework 2.0 et TestProject2 fakes mscorlib.dll pour le .NET Framework 4 produisent tous deux un assembly Fakes mscorlib.Fakes.dll Fakes.

Pour éviter ce problème, Fakes doit créer automatiquement des noms d'assembly Fakes qualifiés par version pour les références hors projet lorsque vous ajoutez le fichier .fakes.Un nom d'assembly Fakes qualifié version inclut un numéro de version lorsque vous créez le nom d'assembly Fakes :

Étant donné un assembly MyAssembly et une version 1.2.3.4, le nom de l'assembly Fakes est MyAssembly.1.2.3.4.Fakes.

Vous pouvez modifier ou supprimer cette version par la modification de l'attribut Version de l'élément Assembly dans le fichier .fakes :

attribute of the Assembly element in the .fakes:
<Fakes ...>
  <Assembly Name="MyAssembly" Version="1.2.3.4" />
  ...
</Fakes>

Fausses conventions d'affectation de noms

Conventions de nommage du type shim et du type stub

Espaces de noms

  • Le suffixe .Fakes est ajouté à l'espace de noms.

    Par exemple, l'espace de noms System.Fakes contient les types shim de l'espace de noms System.

  • Global.Fakes contient le type shim de l'espace de noms vide.

Noms de types

  • Le préfixe shim est ajouté au nom de type pour générer le nom de type shim.

    Par exemple, ShimExample est le type shim du type Example.

  • Le préfixe stub est ajouté au nom de type pour générer le nom de type stub.

    Par exemple, StubIExample est le type stub du type IExample.

Arguments de type et Structures de type imbriquées

  • Les arguments de type générique sont copiés.

  • La structure de type imbriquée est copiée pour les types shim.

Conventions de nommage de la propriété déléguée shim ou du champ délégué stub

Règles de base pour nommer des champs, à partir d'un nom vide :

  • Le nom de la méthode est ajouté.

  • Si le nom de la méthode est une implémentation d'interface explicite, les points sont supprimés.

  • Si la méthode est générique, Ofn est ajouté là où n est le nombre d'arguments de méthode générique.

Les noms des méthodes spéciales telles que les accesseurs Get ou Set des propriétés sont traités comme décrit dans le tableau suivant.

Si la méthode est…

Exemple

Nom de la méthode ajoutée

Un constructeur

.ctor

Constructor

Un constructeur statique

.cctor

StaticConstructor

Un accesseur avec le nom de la méthode composé de deux parties séparées par « _ » (tels que les accesseurs Get de propriété)

kind_name (cas général, mais pas appliqué par ECMA)

NameKind, où les deux parties ont été mises en majuscules et échangées

Accesseur de propriété Get Prop

PropGet

Accesseur Set de propriété Prop

PropSet

Additionneur d'événements

Add

Outil de suppression d'événements

Remove

Un opérateur composé de deux parties

op_name

NameOp

Par exemple : opérateur +

op_Add

AddOp

Pour un opérateur de conversion, le type de retour est ajouté.

T op_Implicit

ImplicitOpT

Remarques

  • Les accesseurs Get et Set des indexeurs sont traités de la même façon que la propriété.Le nom par défaut pour un indexeur est Item.

  • Les noms de type de paramètre sont transformés et concaténés.

  • Le type de retour est ignoré à moins qu'il n'y ait une ambiguïté de surcharge.Si tel est le cas, le type de retour est ajouté à la fin du nom

Conventions d'affectation de nom de type de paramètre

Donné

La chaîne ajoutée est…

Un typeT

T

L'espace de noms, la structure imbriquée, et les tics génériques sont supprimés.

Paramètre de sortieout T

TOut

Un paramètre de référence ref T

TRef

Un type tableauT[]

TArray

Un type tableau multidimensionnelT[ , , ]

T3

Un type pointeurT*

TPtr

Un type génériqueT<R1, …>

TOfR1

Un argument de type générique!i de type C<TType>

Ti

Un argument de méthode générique!!i de méthode M<MMethod>

Mi

Un type imbriquéN.T

N est ajouté, alors T

Règles récursives

Les règles suivantes s'appliquent de manière récursive :

  • Étant donné que Fakes utilise C# pour générer les assemblys Fakes, tout caractère qui produirait un jeton C# non valide est défini en séquence d'échappement « _ » (trait de soulignement).

  • Si un nom résultant est en conflit avec un membre du type déclarant, un modèle de numérotation est utilisé en ajoutant un compteur à deux chiffres commençant à 01.

Ressources externes

Aide

Test de la livraison continue avec Visual Studio 2012 - Chapitre 2 : Tests unitaires : tests

Voir aussi

Concepts

Isolation du code sous test avec Microsoft Fakes