Microsoft Fakes를 사용하여 테스트 중인 코드 격리

응용 프로그램의 다른 부분을 교체 하 여 테스트 하는 코드를 격리 하는 Fake Microsoft 도움말 스텁 또는 shim.이러한 테스트에 의해 제어 되는 작은 코드 조각입니다.테스트 코드를 격리 하 여 테스트에 실패 하면 원인을 돌아가서 다른 곳입니다 요.스텁 및 shim 또한을 응용 프로그램의 다른 부분을 아직 작동 하지 않는 경우에 코드를 테스트할 수 있습니다.

Fake에는 두 가지 방식으로 제공 됩니다.

  • A 스텁 작은 대체 동일한 인터페이스를 구현 하는 클래스를 대체 합니다.스텁을 사용 하 여 각 구성 요소의 인터페이스 에서만 하 고 다른 구성 요소에 따라 달라 집니다. 응용 프로그램을 디자인 해야 합니다.("구성 요소"에서 클래스 또는 그룹 설계와 함께 업데이트 및 일반적으로 어셈블리에 포함 하는 클래스를 의미 합니다.)

  • A shim 지정 된 메서드를 호출 하는 대신 테스트를 제공 하는 shim 코드 실행 되도록 런타임에 응용 프로그램의 컴파일된 코드를 수정 합니다.수정할 수 없는 어셈블리를 해당.NET 어셈블리 호출을 바꾸도록 shim은 사용할 수 있습니다.

다른 구성 요소를 대체하는 Fakes

요구 사항

  • Visual Studio Ultimate

스텁 및 심은 형식 간의 선택

일반적으로 구성 요소를 개발 하 고 이러한 클래스를 동시에 업데이트할 때문에 Visual Studio 프로젝트를 고려해 보겠습니다.스텁 및 shim을 사용 하 여 프로젝트를 솔루션의 다른 프로젝트 또는 프로젝트에서 참조 하는 다른 어셈블리에 게 전화를 고려해 보겠습니다.

다른 참조 된 어셈블리에 호출에 대해 shim 확인 하 고 Visual Studio 솔루션 내의 호출 스텁을 일반 지침으로 사용 합니다.자신의 솔루션에 필요한 빙하 지 않은 방식으로 인터페이스를 정의 하 여 구성 요소를 분리 하는 것이 좋습니다 것을 때문입니다.하지만 대신 shim을 사용 해야 하므로 별도 인터페이스 정의와 외부 어셈블리에서는 System.dll과 같은 일반적으로 제공 되지 않습니다.

다른 고려 사항은 다음과 같습니다.

성능. 런타임에 코드를 다시 작성 하기 때문에 shim을 느리게 실행 합니다.스텁이이 성능 오버 헤드가 없고 가상 메서드 하면서 빠릅니다.

Sealed 형식의 정적 메서드 만 스텁 인터페이스를 구현 하도록 사용할 수 있습니다.따라서 스텁 형식은 사용할 수 없습니다 정적 메서드, 가상이 아닌 메서드, 가상 메서드를 봉인된, sealed 형식 등에 메서드.

내부 형식입니다. Shim와 스텁을 사용할 수 어셈블리 특성을 사용 하 여 액세스할 수 있는 내부 형식과 InternalsVisibleToAttribute.

전용 메서드 모든 형식의 메서드 서명을 표시 되는 경우 shim 개인 메서드 호출을 대체할 수 있습니다.스텁이 표시 방법만 바꿀 수 있습니다.

인터페이스 및 추상 메서드를 제공 합니다. 스텁을 테스트에 사용할 수 있는 추상 메서드 및 인터페이스의 구현을 제공 합니다.메서드 본문이 없으므로 shim 추상 메서드 및 인터페이스를 계측할 수 없습니다.

일반적으로 스텁 형식 내에서 여러분의 코드 기반 종속성에서 격리를 사용 하는 것이 좋습니다.구성 요소 인터페이스 뒤에 숨겨이 수행할 수 있습니다.테스트할 수 있는 API를 제공 하지 않는 타사 구성 요소를 격리할 수 심은 형식은 사용할 수 있습니다.

스텁은 사용 시작

  1. 인터페이스를 주입 합니다.

    스텁을 사용 하려면이 응용 프로그램의 다른 구성 요소에서 클래스를 명시적으로 언급 하지 않는 방식으로 테스트할 코드를 작성 해야 합니다."구성 요소"에서 개발 하 고 함께 업데이트 되어 일반적으로 하나의 Visual Studio 프로젝트에 포함 하는 클래스 또는 클래스 의미 합니다.변수 및 매개 변수 인터페이스를 사용 하 여 선언 해야 하며 다른 구성 요소의 인스턴스를 전달 또는 팩터리를 사용 하 여 만든 해야 합니다.StockFeed 클래스에서 다른 구성 요소는 응용 프로그램의 경우 예를 들어, 다음이 잘못 된 간주 됩니다.

    return (new StockFeed()).GetSharePrice("COOO"); // Bad

    대신,는 다른 구성 요소에서 구현 하는 데 사용 될 수 있으며는 또한 테스트 목적에 대해 스텁을 구현할 수 있는 인터페이스를 정의 합니다.

    public int GetContosoPrice(IStockFeed feed)
    { return feed.GetSharePrice("COOO"); }
    
    Public Function GetContosoPrice(feed As IStockFeed) As Integer
     Return feed.GetSharePrice("COOO")
    End Function
    
  2. Fake 어셈블리를 추가 합니다.

    1. 솔루션 탐색기에서 테스트 프로젝트의 참조 목록을 확장 합니다.Visual Basic 작업 하는 경우를 선택 해야 모든 파일 표시 참조 목록을 확인 합니다.

    2. 인터페이스 (예: IStockFeed)에 정의 된 어셈블리에 대 한 참조를 선택 합니다.이 참조 바로 가기 메뉴에서 선택 Fakes 어셈블리 추가.

    3. 솔루션을 다시 빌드합니다.

  3. 테스트를 스텁의 인스턴스를 생성 하 고 해당 메서드에 대 한 코드를 제공 합니다.

    [TestClass]
    class TestStockAnalyzer
    {
        [TestMethod]
        public void TestContosoStockPrice()
        {
          // Arrange:
    
            // Create the fake stockFeed:
            IStockFeed stockFeed = 
                 new StockAnalysis.Fakes.StubIStockFeed() // Generated by Fakes.
                     {
                         // Define each method:
                         // Name is original name + parameter types:
                         GetSharePriceString = (company) => { return 1234; }
                     };
    
            // In the completed application, stockFeed would be a real one:
            var componentUnderTest = new StockAnalyzer(stockFeed);
    
          // Act:
            int actualValue = componentUnderTest.GetContosoPrice();
    
          // Assert:
            Assert.AreEqual(1234, actualValue);
        }
        ...
    }
    
    <TestClass()> _
    Class TestStockAnalyzer
    
        <TestMethod()> _
        Public Sub TestContosoStockPrice()
            ' Arrange:
            ' Create the fake stockFeed:
            Dim stockFeed As New StockAnalysis.Fakes.StubIStockFeed
            With stockFeed
                .GetSharePriceString = Function(company)
                                           Return 1234
                                       End Function
            End With
            ' In the completed application, stockFeed would be a real one:
            Dim componentUnderTest As New StockAnalyzer(stockFeed)
            ' Act:
            Dim actualValue As Integer = componentUnderTest.GetContosoPrice
            ' Assert:
            Assert.AreEqual(1234, actualValue)
        End Sub
    End Class
    

    여기 마법 부분 특수 클래스인 StubIStockFeed.참조 된 어셈블리의 모든 인터페이스에 대 한 Microsoft Fake 메커니즘 스텁 클래스를 생성합니다.스텁 클래스의 이름을 파생 된 인터페이스의 이름입니다 "Fakes.Stub"로 접두사 및 매개 변수 형식 이름을 추가 합니다.

    Getter 및 setter의 속성, 이벤트 및 제네릭 메서드에 대 한 스텁이 생성 됩니다.자세한 내용은 스텁을 사용하여 단위 테스트를 위한 응용 프로그램의 여러 부분을 서로 격리을 참조하십시오.

Shim으로 시작

구성 요소 호출을 포함 하는 경우 DateTime.Now.

// Code under test:
    public int GetTheCurrentYear()
    {
       return DateTime.Now.Year;
    }

테스트 하는 동안 원하는 shim을 선택의 Now 속성을 실제 버전 간편 하 게 호출할 때마다 다른 값을 반환 하기 때문입니다.

Shim을 사용 하려면 응용 프로그램 코드를 수정 하거나 특정 한 방법으로 쓸 필요가 없습니다.

  1. Fake 어셈블리를 추가 합니다.

    솔루션 탐색기에서 단위 테스트 프로젝트의 참조를 열고 가짜 하려는 메서드가 들어 있는 어셈블리에 대 한 참조를 선택 합니다.이 예제는 DateTime 클래스에는 System.dll.Visual Basic 프로젝트를 참조 하려면 모든 파일 표시.

    선택 Fake 어셈블리 추가.

  2. Shim은 Shimscontext에 삽입

    [TestClass]
    public class TestClass1
    { 
            [TestMethod]
            public void TestCurrentYear()
            {
                int fixedYear = 2000;
    
                // Shims can be used only in a ShimsContext:
                using (ShimsContext.Create())
                {
                  // Arrange:
                    // Shim DateTime.Now to return a fixed date:
                    System.Fakes.ShimDateTime.NowGet = 
                    () =>
                    { return new DateTime(fixedYear, 1, 1); };
    
                    // Instantiate the component under test:
                    var componentUnderTest = new MyComponent();
    
                  // Act:
                    int year = componentUnderTest.GetTheCurrentYear();
    
                  // Assert: 
                    // This will always be true if the component is working:
                    Assert.AreEqual(fixedYear, year);
                }
            }
    }
    
    <TestClass()> _
    Public Class TestClass1
        <TestMethod()> _
        Public Sub TestCurrentYear()
            Using s = Microsoft.QualityTools.Testing.Fakes.ShimsContext.Create()
                Dim fixedYear As Integer = 2000
                ' Arrange:
                ' Detour DateTime.Now to return a fixed date:
                System.Fakes.ShimDateTime.NowGet = _
                    Function() As DateTime
                        Return New DateTime(fixedYear, 1, 1)
                    End Function
    
                ' Instantiate the component under test:
                Dim componentUnderTest = New MyComponent()
                ' Act:
                Dim year As Integer = componentUnderTest.GetTheCurrentYear
                ' Assert: 
                ' This will always be true if the component is working:
                Assert.AreEqual(fixedYear, year)
            End Using
        End Sub
    End Class
    

    심 (shim) 클래스 이름은 이루어집니다 붙임으로써 Fakes.Shim 원본 형식 이름입니다.매개 변수 이름은 메서드 이름에 추가 됩니다.

앞의 예제 shim에 대 한 정적 메서드를 사용합니다.인스턴스 메서드를 사용 하 여 shim을 작성 AllInstances 사이의 형식 이름과 메서드 이름:

System.IO.Fakes.ShimFile.AllInstances.ReadToEnd = ...

특정 인스턴스에 대해, 생성자 및 속성에 대 한 shim을 만들 수도 있습니다.자세한 내용은 shim을 사용하여 단위 테스트를 위한 다른 어셈블리에서 응용 프로그램 격리을 참조하십시오.

이 섹션의 내용

스텁을 사용하여 단위 테스트를 위한 응용 프로그램의 여러 부분을 서로 격리

shim을 사용하여 단위 테스트를 위한 다른 어셈블리에서 응용 프로그램 격리

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