Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este artigo discute opções e problemas na geração e compilação de código do Fakes e descreve as convenções de nomenclatura para tipos, membros e parâmetros gerados por Fakes.
Requisitos
Visual Studio Enterprise
Um projeto do .NET Framework
O suporte para .NET Core, .NET 5.0 ou posterior, e projeto no estilo SDK está em visualização no Visual Studio 2019 Update 6, e é habilitado de forma padrão no Update 8. Para obter mais informações, consulte Microsoft Fakes para projetos no estilo .NET Core e SDK.
Geração e compilação de código
Configurar a geração de código de stubs
A geração de tipos de stub é configurada em um arquivo XML que tem a extensão de arquivo .fakes . A estrutura Fakes se integra ao processo de build por meio de tarefas personalizadas do MSBuild e detecta esses arquivos no momento da compilação. O gerador de código Fakes compila os tipos de stub em um assembly e adiciona a referência ao projeto.
O exemplo a seguir ilustra os tipos de stub definidos em FileSystem.dll:
<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/">
<Assembly Name="FileSystem"/>
</Fakes>
Filtragem de tipo
Os filtros podem ser definidos no arquivo .fakes para restringir quais tipos devem ser definidos. Você pode adicionar um número ilimitado de elementos Clear, Add, Remove sob o elemento StubGeneration para criar a lista de tipos selecionados.
Por exemplo, o arquivo .fakes a seguir gera stubs para tipos nos namespaces System e System.IO, mas exclui qualquer tipo que contenha "Handle" no System:
<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>
As cadeias de caracteres de filtro usam uma gramática simples para definir como a correspondência deve ser feita:
Os filtros não diferenciam maiúsculas de minúsculas por padrão; os filtros executam uma correspondência de subcadeia de caracteres:
elcorresponde a "hello"Adicionar
!ao final do filtro torna-o uma correspondência precisa que diferencia maiúsculas de minúsculas:el!não corresponde a "hello"hello!corresponde a "hello"Adicionar
*ao final do filtro faz com que ele corresponda ao prefixo da cadeia de caracteres:el*não corresponde a "hello"he*corresponde a "hello"Vários filtros em uma lista separada por ponto-e-vírgula são combinados como uma disjunção:
el;wocorresponde a "olá" e "mundo"
Classes concretas de stub e métodos virtuais
Por padrão, os tipos de stub são gerados para todas as classes não lacradas. É possível restringir os tipos de stub a classes abstratas por meio do arquivo de configuração .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>
Tipos internos
O gerador de código Fakes gera tipos de shim e tipos de stub para tipos visíveis ao assembly Fakes criado. Para tornar os tipos internos de um assembly shimmado visíveis para Fakes e seu assembly de teste, adicione atributos InternalsVisibleToAttribute ao código do assembly shimmado que permite a visibilidade do assembly Fakes gerado e do assembly de teste. Veja um exemplo:
// FileSystem\AssemblyInfo.cs
[assembly: InternalsVisibleTo("FileSystem.Fakes")]
[assembly: InternalsVisibleTo("FileSystem.Tests")]
Tipos internos em assemblies fortemente nomeados
Se o assembly shimmed é fortemente nomeado e você quiser acessar os tipos internos do assembly:
O assembly de teste e o assembly Fakes devem ser nomeados de forma estrita.
Adicione as chaves públicas dos assemblies de teste e Fakes nos atributos InternalsVisibleToAttribute nos assemblies shimmed. Veja como os atributos de exemplo no código do assembly shimmed seriam exibidos quando o assembly shimmed for fortemente nomeado:
// FileSystem\AssemblyInfo.cs [assembly: InternalsVisibleTo("FileSystem.Fakes", PublicKey=<Fakes_assembly_public_key>)] [assembly: InternalsVisibleTo("FileSystem.Tests", PublicKey=<Test_assembly_public_key>)]
Se o assembly shimmed for fortemente nomeado, a estrutura Fakes assinará automaticamente o assembly Fakes gerado automaticamente. Você precisa assinar fortemente o assembly de teste. Consulte Strong-Named assemblies.
A estrutura Fakes usa a mesma chave para assinar todos os assemblies gerados, de modo que você possa usar esse snippet como ponto de partida para adicionar o atributo InternalsVisibleTo no assembly fakes ao código do seu assembly shimmed.
[assembly: InternalsVisibleTo("FileSystem.Fakes, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e92decb949446f688ab9f6973436c535bf50acd1fd580495aae3f875aa4e4f663ca77908c63b7f0996977cb98fcfdb35e05aa2c842002703cad835473caac5ef14107e3a7fae01120a96558785f48319f66daabc862872b2c53f5ac11fa335c0165e202b4c011334c7bc8f4c4e570cf255190f4e3e2cbc9137ca57cb687947bc")]
Você pode especificar uma chave pública diferente para o assembly Fakes, como uma chave que você criou para o assembly shimmed, especificando o caminho completo para o arquivo .snk que contém a chave alternativa como valor do atributo KeyFile no elemento Fakes\Compilation do arquivo .fakes. Por exemplo:
<-- FileSystem.Fakes.fakes -->
<Fakes ...>
<Compilation KeyFile="full_path_to_the_alternate_snk_file" />
</Fakes>
Em seguida, você precisa usar a chave pública do arquivo .snk alternativo como o segundo parâmetro do atributo InternalVisibleTo para o assembly Fakes no código do assembly shimmed:
// FileSystem\AssemblyInfo.cs
[assembly: InternalsVisibleTo("FileSystem.Fakes",
PublicKey=<Alternate_public_key>)]
[assembly: InternalsVisibleTo("FileSystem.Tests",
PublicKey=<Test_assembly_public_key>)]
No exemplo acima, os valores Alternate_public_key e os Test_assembly_public_key podem ser os mesmos.
Otimizar tempos de build
A compilação de assemblies Fakes pode aumentar significativamente o tempo de compilação. Você pode minimizar o tempo de compilação gerando os assemblies falsos para assemblies do sistema .NET e assemblies de terceiros em um projeto centralizado separado. Como as montagens raramente são alteradas em seu computador, você pode reutilizar os Fakes assemblies gerados em outros projetos.
Em seus projetos de testes unitários, adicione uma referência aos assemblies Fakes compilados que são colocados em FakesAssemblies na pasta do projeto.
Crie uma nova Biblioteca de Classes com a versão de runtime do .NET que corresponda aos seus projetos de teste. Vamos chamá-lo de Fakes.Prebuild. Remova o arquivo class1.cs do projeto, não necessário.
Adicione referência a todos os assemblies do Sistema e de terceiros para os quais você precisa de Fakes.
Adicione um arquivo .fakes para cada um dos assemblies e build.
Do seu projeto de teste
Certifique-se de ter uma referência à DLL de tempo de execução do Fakes.
%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\PublicAssemblies\Microsoft.QualityTools.Testing.Fakes.dll
Para cada assembly para o qual você criou Fakes, adicione uma referência ao arquivo DLL correspondente na pasta Fakes.Prebuild\FakesAssemblies do seu projeto.
Evitar conflitos de nome do assembly
Em um ambiente de Team Build, todos os resultados de build são mesclados em um único diretório. Se vários projetos usarem Fakes, pode acontecer que as assemblies Fakes de diferentes versões entrem em conflito entre si. Por exemplo, o TestProject1 falsifica o mscorlib.dll do .NET Framework 2.0 e o TestProject2 falsifica o mscorlib.dll para o .NET Framework 4, ambos resultariam em um assembly de Fakes mscorlib.Fakes.dll.
Para evitar esse problema, os Fakes devem criar automaticamente nomes de assembly Fakes qualificados por versão para referências que não sejam de projeto ao adicionar os arquivos .fakes. Um nome de assembly Fakes qualificado por versão incorpora um número de versão ao se criar o nome do assembly Fakes.
Dado um assembly MyAssembly e uma versão 1.2.3.4, o nome do assembly Fakes é MyAssembly.1.2.3.4.Fakes.
Você pode alterar ou remover essa versão editando o atributo Version do elemento Assembly no .fakes:
attribute of the Assembly element in the .fakes:
<Fakes ...>
<Assembly Name="MyAssembly" Version="1.2.3.4" />
...
</Fakes>
Convenções de nomenclatura falsas
Convenções de nomenclatura de tipos de shim e de stub
Namespaces
. O sufixo Fakes é adicionado ao namespace.
Por exemplo,
System.Fakeso namespace contém os tipos de shim do namespace System.Global.Fakes contém o tipo shim do namespace vazio.
Nomes de tipo
O prefixo Shim é adicionado ao nome do tipo para criar o nome do tipo shim.
Por exemplo, ShimExample é o tipo shim do tipo Example.
O prefixo stub é adicionado ao nome do tipo para criar o nome do tipo stub.
Por exemplo, StubIExample é o tipo stub do tipo IExample.
Argumentos de tipo e estruturas de tipo aninhadas
Argumentos de tipo genérico são copiados.
A estrutura de tipo aninhado é copiada para os tipos de shim.
Convenções de nomenclatura para propriedades de delegado shim ou campos de delegado stub
Regras básicas para nomenclatura de campo, começando por um nome vazio:
O nome do método é acrescentado.
Se o nome do método for uma implementação de interface explícita, os pontos serão removidos.
Se o método for genérico,
Ofn será acrescentado em que n é o número de argumentos de método genérico.Nomes de métodos especiais, como getters ou setters de propriedades, são tratados conforme descrito na tabela a seguir:
| Se o método for... | Example | Nome do método acrescentado |
|---|---|---|
| Um construtor | .ctor |
Constructor |
| Um construtor estático | .cctor |
StaticConstructor |
| Um acessor com o nome do método composto por duas partes separadas por "_" (tais como getters de propriedade) | kind_name (caso comum, mas não imposto pelo ECMA) | NameKind, onde ambas as partes foram maiúsculas e trocadas |
Getter da propriedade Prop |
PropGet |
|
Definidor de propriedade Prop |
PropSet |
|
| Adicionador de eventos | Add |
|
| Removedor de eventos | Remove |
|
| Um operador composto por duas partes | op_name |
NameOp |
| Por exemplo: + operador | op_Add |
AddOp |
| Para um operador de conversão, o tipo de retorno é acrescentado. | T op_Implicit |
ImplicitOpT |
Observação
-
Getters e setters de indexadores são tratados de forma semelhante às propriedades. O nome padrão de um indexador é
Item. - Os nomes dos tipos de parâmetro são transformados e concatenados.
- O tipo de retorno é ignorado, a menos que haja uma ambiguidade de sobrecarga. Se houver uma ambiguidade de sobrecarga, o tipo de retorno será adicionado ao final do nome.
Convenções de nomenclatura de tipo de parâmetro
| Dado | A string adicionada é... |
|---|---|
Um tipoT |
T O namespace, a estrutura aninhada e os tiques genéricos são descartados. |
Um parâmetro de saídaout T |
TOut |
Um parâmetro refref T |
TRef |
Um tipo de matrizT[] |
TArray |
Um tipo de matriz multidimensionalT[ , , ] |
T3 |
Um tipo de ponteiroT* |
TPtr |
Um tipo genéricoT<R1, ...> |
TOfR1 |
Um argumento!i de tipo genérico do tipo C<TType> |
Ti |
Um argumento de método genérico!!i do método M<MMethod> |
Mi |
Um tipo aninhadoN.T |
N é acrescentado, em seguida, T |
Regras recursivas
As seguintes regras são aplicadas recursivamente:
Como o Fakes usa C# para gerar os assemblies do Fakes, qualquer caractere que produza um token C# inválido é substituído por "_" (underscore).
Se um nome resultante estiver em conflito com qualquer membro do tipo de declaração, um esquema de numeração será usado acrescentando um contador de dois dígitos, começando em 01.
Utilizando o Microsoft Fakes na integração contínua
Geração de assembly do Microsoft Fakes
O Microsoft Fakes é um recurso disponível exclusivamente no Visual Studio Enterprise. Dessa forma, a geração de Assemblies de Teste exige o uso da Tarefa de Build do Visual Studio ao construir seu projeto.
Observação
Uma estratégia alternativa envolve registrar diretamente seus Fakes Assemblies no sistema de Integração Contínua (CI) e utilizar a MSBuild Task. Se você optar por essa abordagem, precisará incluir uma referência de assembly ao Fakes assembly gerado em seu projeto de teste, conforme mostrado no seguinte trecho de código:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<Reference Include="FakesAssemblies\System.Fakes.dll"/>
</ItemGroup>
</Project>
Essa referência deve ser adicionada manualmente, especificamente para projetos no estilo SDK (ou seja, .NET Core, .NET 5+e .NET Framework), pois esses projetos agora adicionam implicitamente referências de assembly. Se você decidir usar esse método, atualize o assembly Fakes sempre que o assembly pai passar por alterações.