다음을 통해 공유


Microsoft Fakes의 코드 생성, 컴파일 및 명명 규칙

이 문서에서는 Fakes 코드 생성 및 컴파일의 옵션 및 문제에 대해 설명하고 Fakes에서 생성된 형식, 멤버 및 매개 변수에 대한 명명 규칙을 설명합니다.

요구 사항

코드 생성 및 컴파일

스텁 코드 생성 설정

스텁 형식의 생성은 .fakes 파일 확장자를 포함하는 XML 파일에서 구성됩니다. Fakes 프레임워크는 사용자 지정 MSBuild 작업을 통해 빌드 프로세스에 통합되고 빌드 시 해당 파일을 검색합니다. Fakes 코드 생성기는 스텁 형식을 어셈블리로 컴파일하고 프로젝트에 참조를 추가합니다.

다음 예제에서는 FileSystem.dll정의된 스텁 형식을 보여 줍니다.

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

형식 필터링

.fakes 파일에서 필터를 설정하여 스텁해야 하는 형식을 제한할 수 있습니다. StubGeneration 요소 아래에 바인딩되지 않은 수의 Clear, Add, Remove 요소를 추가하여 선택한 형식 목록을 작성할 수 있습니다.

예를 들어 다음 .fakes 파일은 시스템 및 System.IO 네임스페이스에 있는 형식에 대한 스텁을 생성하지만 시스템에서 "Handle"를 포함하는 형식은 제외합니다.

<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>

필터 문자열은 간단한 문법을 사용하여 일치를 수행하는 방법을 정의합니다.

  • 필터는 기본적으로 대/소문자를 구분하지 않습니다. 필터는 부분 문자열 일치를 수행합니다.

    el는 "hello"와 일치합니다.

  • 필터 끝에 !를 추가하면 대/소문자를 구분하여 정확히 일치시킬 수 있습니다.

    el! "hello"가 일치하지 않습니다.

    hello!는 "hello"와 일치합니다.

  • 필터의 끝에 추가 * 하면 문자열의 접두사와 일치합니다.

    el* "hello"가 일치하지 않습니다.

    he*는 "hello"와 일치합니다.

  • 세미콜론으로 구분된 목록의 여러 필터는 분리로 결합됩니다.

    el;wo 는 "hello" 및 "world"와 일치합니다.

스텁 구체적인 클래스 및 가상 메서드

기본적으로 스텁 형식은 봉인되지 않은 모든 클래스에 대해 생성됩니다. .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>

내부 형식

Fakes 코드 생성기는 생성된 Fakes 어셈블리에서 접근 가능한 형식에 대해 shim 타입과 stub 타입을 생성합니다. 내부 형식의 shimmed 어셈블리를 Fakes 및 테스트 어셈블리에서 볼 수 있도록 하려면 생성된 Fakes 어셈블리와 테스트 어셈블리에 대한 가시성을 제공하는 특성을 shimmed 어셈블리 코드에 InternalsVisibleToAttribute 추가하십시오. 예제는 다음과 같습니다.

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

강력한 이름의 어셈블리의 내부 형식

shim 처리된 어셈블리가 강력한 이름을 가지고 있고 어셈블리의 내부 타입에 액세스하려는 경우:

  • 테스트 어셈블리와 Fakes 어셈블리 둘 다 강력한 이름을 가져야 합니다.

  • 테스트 및 Fakes 어셈블리의 공개 키를 shimmed 어셈블리의 InternalsVisibleToAttribute 특성에 추가합니다. shimmed 어셈블리의 이름이 강력한 경우 shimmed 어셈블리 코드의 예제 특성은 다음과 같습니다.

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

shimmed 어셈블리에 강력한 이름이 있는 경우에, Fakes 프레임워크는 생성된 Fakes 어셈블리에 대해 자동으로 강력한 서명을 합니다. 테스트 어셈블리에 강력한 서명을 해야 합니다. Strong-Named 어셈블리를 참조하세요.

Fakes 프레임워크는 동일한 키를 사용하여 생성된 모든 어셈블리에 서명하므로 이 코드 조각을 시작점으로 사용하여 fakes 어셈블리에 대한 InternalsVisibleTo 특성을 스시밍된 어셈블리 코드에 추가할 수 있습니다.

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

대체 키를 포함하는 .snk 파일의 전체 경로를 .fakes 파일의 KeyFileFakes\Compilation 요소의 특성 값으로 지정하여, Fakes 어셈블리에 대해 만든 공개 키나 시뮬레이션된 어셈블리에 대해 만든 다른 공개 키를 지정할 수 있습니다. 다음은 그 예입니다.

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

그런 다음, 시밍된 어셈블리 코드에서 Fakes 어셈블리에 대한 InternalVisibleTo 특성의 두 번째 매개 변수로 대체 .snk 파일의 공개 키를 사용해야 합니다.

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

위의 예제에서 Alternate_public_key 값과 Test_assembly_public_key 값이 동일할 수 있습니다.

빌드 시간 최적화

Fakes 어셈블리의 컴파일은 빌드 시간을 크게 늘릴 수 있습니다. 별도의 중앙 집중식 프로젝트에서 .NET 시스템 어셈블리 및 타사 어셈블리에 대한 Fakes 어셈블리를 생성하여 빌드 시간을 최소화할 수 있습니다. 이러한 어셈블리는 컴퓨터에서 거의 변경되지 않으므로 생성된 Fakes 어셈블리를 다른 프로젝트에서 다시 사용할 수 있습니다.

단위 테스트 프로젝트에서 프로젝트 폴더의 FakesAssemblies 아래에 배치되는 컴파일된 Fakes 어셈블리에 대한 참조를 추가합니다.

  1. 테스트 프로젝트와 일치하는 .NET 런타임 버전을 사용하여 새 클래스 라이브러리를 만듭니다. Fakes.Prebuild라고 하겠습니다. 프로젝트에서 class1.cs 파일을 제거할 필요가 없습니다.

  2. Fakes가 필요한 모든 시스템 및 타사 어셈블리에 대한 참조를 추가합니다.

  3. 각 어셈블리에 .fakes 파일을 추가하고 빌드합니다.

  4. 테스트 프로젝트에서

    • Fakes 런타임 DLL에 대한 참조가 있는지 확인합니다.

      %ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\PublicAssemblies\Microsoft.QualityTools.Testing.Fakes.dll

    • Fakes를 만든 각 어셈블리에 대해 프로젝트의 Fakes.Prebuild\FakesAssemblies 폴더에 해당 DLL 파일에 대한 참조를 추가합니다.

어셈블리 이름 충돌 방지

팀 빌드 환경에서 모든 빌드 출력은 단일 디렉터리에 병합됩니다. 여러 프로젝트에서 Fakes를 사용하는 경우 서로 다른 버전의 Fakes 어셈블리가 서로 덮어쓰게 될 수 있습니다. 예를 들어, TestProject1은 .NET Framework 2.0의 mscorlib.dll을 가짜로 만들고, TestProject2는 .NET Framework 4의 mscorlib.dll을 가짜로 만들면 둘 다 mscorlib.Fakes.dll Fakes 어셈블리를 생성합니다.

이 문제를 방지하기 위해 Fakes는 .fakes 파일을 추가할 때 프로젝트 이외의 참조에 대한 버전 정규화된 Fakes 어셈블리 이름을 자동으로 만들어야 합니다. Fakes 어셈블리 이름을 만들 때 버전 정규화된 Fakes 어셈블리 이름은 버전 번호를 포함합니다.

지정된 어셈블리 MyAssembly와 버전 1.2.3.4의 Fakes 어셈블리 이름은 MyAssembly.1.2.3.4.Fakes입니다.

.fakes에서 Assembly 요소의 Version 특성을 편집하여 이 버전을 변경하거나 제거할 수 있습니다.

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

가짜 명명 규칙

Shim 형식 및 스텁 형식 명명 규칙

Namespaces

  • . Fakes 접미사가 네임스페이스에 추가됩니다.

    예를 들어 System.Fakes 네임스페이스에는 System 네임스페이스의 shim 타입이 포함됩니다.

  • Global.Fakes에는 빈 네임스페이스의 shim 형식이 포함됩니다.

    형식 이름

  • Shim 접두사는 shim 형식 이름을 작성하기 위해 형식 이름에 추가됩니다.

    예를 들어 ShimExample은 예제 형식의 shim 형식입니다.

  • 형식 이름에 스텁 접두사를 추가하여 스텁 형식 이름을 구성합니다.

    예를 들어 StubIExample은 IExample 형식의 스텁 형식입니다.

    형식 인수 및 중첩된 형식 구조체

  • 제네릭 형식 인수가 복사됩니다.

  • 중첩된 형식 구조체는 shim 형식에 대해 복사됩니다.

Shim 대리자 속성 또는 스텁 대리자 필드 명명 규칙

빈 이름에서 시작하여 필드 이름 지정에 대한 기본 규칙:

  • 메서드 이름이 추가됩니다.

  • 메서드 이름이 명시적 인터페이스 구현인 경우 점이 제거됩니다.

  • 메서드가 제네릭 Of 이면 n이 추가됩니다. 여기서 n은 제네릭 메서드 인수의 수입니다.

    속성 getter 또는 setter와 같은 특수 메서드 이름은 다음 표에 설명된 대로 처리됩니다.

메서드가 ...인 경우 Example 추가된 메서드 이름
생성자 .ctor Constructor
정적 생성자 .cctor StaticConstructor
메서드 이름이 "_"로 구분된 두 부분으로 구성된 접근자 메서드(예: 속성 getter). kind_name (일반적인 경우이지만 ECMA에 의해 적용되지 않음) NameKind, 두 부분 모두 대문자화 및 교환
Prop의 Getter 속성 PropGet
속성의 설정자 Prop PropSet
이벤트 추가기 Add
이벤트 제거기 Remove
두 부분으로 구성된 연산 op_name NameOp
예: + 연산자 op_Add AddOp
변환 연산자의 경우 반환 형식이 추가됩니다. T op_Implicit ImplicitOpT

비고

  • 인덱서의 Getter 및 setter 는 속성과 유사하게 처리됩니다. 인덱서의 기본 이름은 .입니다 Item.
  • 매개 변수 형식 이름이 변환되고 연결됩니다.
  • 오버로드 모호성이 없는 경우 반환 형식은 무시됩니다. 오버로드 모호성이 있는 경우 이름 끝에 반환 형식이 추가됩니다.

매개 변수 형식 명명 규칙

지정된 조건 추가된 문자열은...
형식T T

네임스페이스, 중첩 구조체 및 제네릭 tic이 삭제됩니다.
out 매개 변수out T TOut
ref 매개 변수ref T TRef
배열 형식T[] TArray
다차원 배열 형식T[ , , ] T3
포인터 형식T* TPtr
제네릭 형식T<R1, ...> TOfR1
형식의 제네릭 형식 인수!iC<TType> Ti
메서드의 제네릭 메서드 인수!!iM<MMethod> Mi
중첩 형식N.T N 가 추가된 다음 T

재귀 규칙

다음 규칙은 재귀적으로 적용됩니다.

  • Fakes는 C#을 사용하여 Fakes 어셈블리를 생성하기 때문에 잘못된 C# 토큰을 생성하는 모든 문자는 "_"(밑줄)로 이스케이프됩니다.

  • 생성된 이름이 선언 형식의 멤버와 충돌하는 경우 01부터 시작하는 두 자리 숫자를 추가하여 번호 매기기 체계를 사용합니다.

연속 통합에서 Microsoft Fakes 활용

Microsoft Fakes 어셈블리 생성

Microsoft Fakes는 Visual Studio Enterprise에서만 사용할 수 있는 기능입니다. 따라서 Fakes 어셈블리를 생성하려면 프로젝트를 빌드할 때 Visual Studio 빌드 태스크 를 사용해야 합니다.

비고

대체 전략에는 Fakes 어셈블리를 CI(연속 통합) 시스템에 직접 확인하고 MSBuild 작업을 활용하는 것이 포함됩니다. 이 방법을 선택하는 경우 다음 코드 조각과 같이 생성된 Fakes 어셈블리에 대한 어셈블리 참조를 테스트 프로젝트에 포함해야 합니다.

<Project Sdk="Microsoft.NET.Sdk">
    <ItemGroup>
        <Reference Include="FakesAssemblies\System.Fakes.dll"/>
    </ItemGroup>
</Project>

이러한 프로젝트는 이제 어셈블리 참조를 암시적으로 추가하므로 SDK 스타일 프로젝트(즉, .NET Core, .NET 5 이상 및 .NET Framework)에 대해 이 참조를 수동으로 추가해야 합니다. 이 메서드를 사용하려는 경우 부모 어셈블리가 변경될 때마다 Fakes 어셈블리를 업데이트해야 합니다.