Konwencje dotyczące generowania, kompilowania i nazywania w Microsoft Fakes
W tym artykule omówiono opcje i problemy związane z generowaniem i kompilacją kodu Fakes oraz opisano konwencje nazewnictwa dla typów generowanych przez fakes, elementów członkowskich i parametrów.
Wymagania
Visual Studio Enterprise
Projekt programu .NET Framework
.NET Core, .NET 5.0 lub nowszy oraz obsługa projektu w stylu zestawu SDK w wersji zapoznawczej w programie Visual Studio 2019 Update 6 i jest domyślnie włączona w aktualizacji Update 8. Aby uzyskać więcej informacji, zobacz Microsoft Fakes for .NET Core and SDK-style projects (Aplikacje Microsoft Fakes dla platformy .NET Core i projektów w stylu zestawu SDK).
Generowanie i kompilacja kodu
Konfigurowanie generowania kodu wycinków
Generowanie typów wycinków jest konfigurowane w pliku XML, który ma rozszerzenie pliku .fakes . Platforma Fakes integruje się w procesie kompilacji za pomocą niestandardowych zadań MSBuild i wykrywa te pliki w czasie kompilacji. Generator kodu Fakes kompiluje typy wycinków do zestawu i dodaje odwołanie do projektu.
Poniższy przykład ilustruje typy wycinków zdefiniowane w FileSystem.dll:
<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/">
<Assembly Name="FileSystem"/>
</Fakes>
Filtrowanie typów
Filtry można ustawić w pliku .fakes , aby ograniczyć typy, które powinny być stubbed. Możesz dodać niezwiązaną liczbę elementów Clear, Add, Remove w elemecie StubGeneration, aby utworzyć listę wybranych typów.
Na przykład następujący plik .fakes generuje wycinki typów w obszarze System i System.IO przestrzeni nazw, ale wyklucza dowolny typ zawierający ciąg "Handle" w systemie:
<Fakes xmlns="http://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>
Ciągi filtrów używają prostej gramatyki, aby zdefiniować sposób wykonywania dopasowywania:
Filtry są domyślnie niewrażliwe na wielkość liter; filtry wykonują dopasowywanie podciągów:
el
pasuje do "hello"Dodanie
!
na końcu filtru sprawia, że jest to dokładne dopasowanie z uwzględnieniem wielkości liter:el!
nie pasuje do "hello"hello!
pasuje do "hello"Dodanie
*
na końcu filtru sprawia, że jest ono zgodne z prefiksem ciągu:el*
nie pasuje do "hello"he*
pasuje do "hello"Wiele filtrów na liście rozdzielanej średnikami jest połączonych jako rozłączenie:
el;wo
pasuje do "hello" i "world"
Klasy betonowe wycinków i metody wirtualne
Domyślnie typy wycinków są generowane dla wszystkich klas, które nie są zapieczętowane. Istnieje możliwość ograniczenia typów wycinków do abstrakcyjnych klas za pomocą pliku konfiguracji .fakes :
<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/">
<Assembly Name="mscorlib" />
<!-- user code -->
<StubGeneration>
<Types>
<Clear />
<Add AbstractClasses="true"/>
</Types>
</StubGeneration>
<!-- /user code -->
</Fakes>
Typy wewnętrzne
Generator kodu Fakes generuje typy podkładek i typy wycinków dla typów widocznych dla wygenerowanego zestawu Fakes. Aby utworzyć wewnętrzne typy zestawu shimmed widoczne dla Fakes i zestawu testowego, dodaj InternalsVisibleToAttribute atrybuty do shimmed kodu zestawu, który zapewnia widoczność wygenerowanego zestawu Fakes i do zestawu testowego. Oto przykład:
// FileSystem\AssemblyInfo.cs
[assembly: InternalsVisibleTo("FileSystem.Fakes")]
[assembly: InternalsVisibleTo("FileSystem.Tests")]
Typy wewnętrzne w silnie nazwanych zestawach
Jeśli zestaw shimmed jest silnie nazwany i chcesz uzyskać dostęp do typów wewnętrznych zestawu:
Zarówno zestaw testowy, jak i zestaw Fakes muszą być silnie nazwane.
Dodaj klucze publiczne zestawu testowego i fakes do atrybutów InternalsVisibleToAttribute w zestawach z podkładkami. Oto, jak przykładowe atrybuty w kodzie zestawu shimmed będą wyglądać, gdy zestaw shimmed jest silnie nazwany:
// FileSystem\AssemblyInfo.cs [assembly: InternalsVisibleTo("FileSystem.Fakes", PublicKey=<Fakes_assembly_public_key>)] [assembly: InternalsVisibleTo("FileSystem.Tests", PublicKey=<Test_assembly_public_key>)]
Jeśli zestaw shimmed jest silnie nazwany, platforma Fakes automatycznie podpisuje wygenerowany zestaw Fakes. Musisz podpisać silny podpis zestawu testowego. Zobacz Zestawy o silnych nazwach.
Struktura Fakes używa tego samego klucza do podpisywania wszystkich wygenerowanych zestawów, więc można użyć tego fragmentu kodu jako punktu początkowego, aby dodać atrybut InternalsVisibleTo dla zestawu fakes do kodu zestawu shimmed.
[assembly: InternalsVisibleTo("FileSystem.Fakes, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e92decb949446f688ab9f6973436c535bf50acd1fd580495aae3f875aa4e4f663ca77908c63b7f0996977cb98fcfdb35e05aa2c842002703cad835473caac5ef14107e3a7fae01120a96558785f48319f66daabc862872b2c53f5ac11fa335c0165e202b4c011334c7bc8f4c4e570cf255190f4e3e2cbc9137ca57cb687947bc")]
Dla zestawu Fakes można określić inny klucz publiczny, taki jak klucz utworzony dla zestawu shimmed, określając pełną ścieżkę do pliku snk, który zawiera klucz alternatywny jako KeyFile
wartość atrybutu w\Fakes
Compilation
elemencie pliku .fakes. Na przykład:
<-- FileSystem.Fakes.fakes -->
<Fakes ...>
<Compilation KeyFile="full_path_to_the_alternate_snk_file" />
</Fakes>
Następnie musisz użyć klucza publicznego alternatywnego pliku snk jako drugiego parametru atrybutu InternalVisibleTo dla zestawu Fakes w kodzie zestawu shimmed:
// FileSystem\AssemblyInfo.cs
[assembly: InternalsVisibleTo("FileSystem.Fakes",
PublicKey=<Alternate_public_key>)]
[assembly: InternalsVisibleTo("FileSystem.Tests",
PublicKey=<Test_assembly_public_key>)]
W powyższym przykładzie wartości Alternate_public_key
i wartości Test_assembly_public_key
mogą być takie same.
Optymalizowanie czasów kompilacji
Kompilacja zestawów Fakes może znacznie zwiększyć czas kompilacji. Czas kompilacji można zminimalizować, generując zestawy Fakes dla zestawów .NET System i zestawów innych firm w osobnym scentralizowanym projekcie. Ponieważ takie zestawy rzadko zmieniają się na maszynie, można ponownie użyć wygenerowanych zestawów Fakes w innych projektach.
Z projektów testów jednostkowych dodaj odwołanie do skompilowanych zestawów Fakes, które są umieszczane w folderze projektu FakesAssemblies.
Utwórz nową bibliotekę klas z wersją środowiska uruchomieniowego platformy .NET zgodną z projektami testowymi. Nazwijmy to Fakes.Prebuild. Usuń plik class1.cs z projektu, który nie jest potrzebny.
Dodaj odwołanie do wszystkich zestawów systemowych i innych firm, dla których potrzebujesz aplikacji Fakes.
Dodaj plik .fakes dla każdego zestawu i kompilacji.
Z projektu testowego
Upewnij się, że masz odwołanie do biblioteki DLL środowiska uruchomieniowego Fakes:
%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\PublicAssemblies\Microsoft.QualityTools.Testing.Fakes.dll
Dla każdego zestawu, dla którego utworzono narzędzia Fakes, dodaj odwołanie do odpowiedniego pliku DLL w folderze Fakes.Prebuild\FakesAssemblies projektu.
Unikaj starcia nazw zestawów
W środowisku kompilacji zespołowej wszystkie dane wyjściowe kompilacji są scalane z jednym katalogiem. Jeśli wiele projektów używa fakes, może się zdarzyć, że zestawy Fakes z różnych wersji przesłaniają się nawzajem. Na przykład podróbki TestProject1 mscorlib.dll z programów .NET Framework 2.0 i TestProject2 mscorlib.dll dla platformy .NET Framework 4 dałyby wynik do biblioteki mscorlib. zestaw Fakes.dll Fakes.
Aby uniknąć tego problemu, fakes powinien automatycznie utworzyć kwalifikowane nazwy zestawów Fakes dla odwołań nieprojektowych podczas dodawania plików .fakes . Kwalifikowana wersja nazwa zestawu Fakes osadza numer wersji podczas tworzenia nazwy zestawu Fakes:
Biorąc pod uwagę zestaw MyAssembly i wersję 1.2.3.4, nazwa zestawu Fakes to MyAssembly.1.2.3.4.Fakes.
Tę wersję można zmienić lub usunąć, edytując atrybut Version elementu Assembly w pliku .fakes:
attribute of the Assembly element in the .fakes:
<Fakes ...>
<Assembly Name="MyAssembly" Version="1.2.3.4" />
...
</Fakes>
Konwencje nazewnictwa fakes
Konwencje nazewnictwa typów podkładek i wycinków
Przestrzenie nazw
. Sufiks fakes jest dodawany do przestrzeni nazw.
Na przykład
System.Fakes
przestrzeń nazw zawiera typy podkładek przestrzeni nazw systemu.Global.Fakes zawiera typ podkładki pustej przestrzeni nazw.
Nazwy typów
Prefiks podkładki jest dodawany do nazwy typu w celu skompilowania nazwy typu podkładki.
Na przykład ShimExample jest typem podkładki typu Example.
Prefiks wycinków jest dodawany do nazwy typu w celu skompilowania nazwy typu wycinkowego.
Na przykład StubIExample jest typem wycinkowym typu IExample.
Argumenty typu i zagnieżdżone struktury typów
Argumenty typu ogólnego są kopiowane.
Struktura typu zagnieżdżonego jest kopiowana dla typów podkładek.
Podkładka delegowana właściwość lub konwencje nazewnictwa pól delegata wycinków
Podstawowe reguły nazewnictwa pól, zaczynając od pustej nazwy:
Nazwa metody jest dołączana.
Jeśli nazwa metody jest jawną implementacją interfejsu, kropki zostaną usunięte.
Jeśli metoda jest ogólna, n jest dołączany,
Of
gdzie n jest liczbą argumentów metody ogólnej.Specjalne nazwy metod, takie jak getter właściwości lub metody ustawiania, są traktowane zgodnie z opisem w poniższej tabeli:
Jeśli metoda jest... | Przykład | Dołączona nazwa metody |
---|---|---|
Konstruktor | .ctor |
Constructor |
Konstruktor statyczny | .cctor |
StaticConstructor |
Metoda dostępu zawierająca nazwę metody składającą się z dwóch części oddzielonych ciągiem "_" (na przykład metod getters właściwości) | kind_name (typowy przypadek, ale nie wymuszany przez ECMA) | NameKind, gdzie obie części zostały skapitalizowane i zamienione |
Getter właściwości Prop |
PropGet |
|
Setter właściwości Prop |
PropSet |
|
Dodatek zdarzeń | Add |
|
Usuwanie zdarzeń | Remove |
|
Operator składający się z dwóch części | op_name |
NameOp |
Na przykład: + operator | op_Add |
AddOp |
W przypadku operatora konwersji typ zwracany jest dołączany. | T op_Implicit |
ImplicitOpT |
Uwaga
- Metody pobierające i ustawiacze indeksatorów są traktowane podobnie jak właściwość . Domyślną nazwą indeksatora jest
Item
. - Nazwy typów parametrów są przekształcane i łączone.
- Zwracany typ jest ignorowany, chyba że istnieje niejednoznaczność przeciążenia. Jeśli występuje niejednoznaczność przeciążenia, zwracany typ jest dołączany na końcu nazwy.
Konwencje nazewnictwa typów parametrów
Dany | Dołączony ciąg jest... |
---|---|
TypT |
T Przestrzeń nazw, struktura zagnieżdżona i ogólne tics są porzucane. |
Parametr wyjściowyout T |
TOut |
Parametr ref ref T |
TRef |
Typ tablicyT[] |
TArray |
Wielowymiarowy typ tablicyT[ , , ] |
T3 |
Typ wskaźnikaT* |
TPtr |
Typ ogólnyT<R1, ...> |
TOfR1 |
Argument !i typu ogólnego typu typuC<TType> |
Ti |
Ogólny argument!!i metody metody M<MMethod> |
Mi |
Typ zagnieżdżonyN.T |
N jest dołączany, a następnie T |
Reguły cykliczne
Następujące reguły są stosowane rekursywnie:
Ponieważ fakes używa języka C# do generowania zestawów Fakes, każdy znak, który wygenerowałby nieprawidłowy token języka C#, zostanie uniknięty do znaku "_" (podkreślenie).
Jeśli wynikowa nazwa zderza się z dowolnym elementem członkowskim typu deklarowanego, schemat numeracji jest używany przez dołączenie dwucyfrowego licznika, zaczynając od 01.
Wykorzystanie fałszywych elementów firmy Microsoft w ciągłej integracji
Microsoft Fakes Assembly Generation
Microsoft Fakes to funkcja dostępna wyłącznie w programie Visual Studio Enterprise. W związku z tym generowanie zestawów Fakes wymaga użycia zadania kompilacji programu Visual Studio podczas kompilowania projektu.
Uwaga
Alternatywna strategia polega na sprawdzeniu zestawów fakes bezpośrednio w systemie ciągłej integracji i wykorzystaniu zadania MSBuild. Jeśli zdecydujesz się na to podejście, musisz uwzględnić odwołanie do zestawu wygenerowanego zestawu Fakes w projekcie testowym, jak pokazano w poniższym fragmencie kodu:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<Reference Include="FakesAssemblies\System.Fakes.dll"/>
</ItemGroup>
</Project>
To odwołanie należy dodać ręcznie, szczególnie w przypadku projektów w stylu zestawu SDK (czyli .NET Core, .NET 5+i .NET Framework), ponieważ te projekty teraz niejawnie dodają odwołania do zestawów. Jeśli zdecydujesz się użyć tej metody, pamiętaj, aby zaktualizować zestaw Fakes za każdym razem, gdy zestaw nadrzędny przejdzie zmiany.