스텁을 사용하여 유닛 테스트를 위한 응용 프로그램의 여러 부분을 서로 격리Using stubs to isolate parts of your application from each other for unit testing

스텁 유형은 테스트하는 구성 요소를 이러한 구성 요소가 호출하는 다른 구성 요소에서 쉽게 격리할 수 있도록 Microsoft Fakes 프레임워크에서 제공하는 두 가지 기술 중 하나입니다.Stub types are one of two technologies that the Microsoft Fakes framework provides to let you easily isolate a component you are testing from other components that it calls. 스텁은 테스트 중 다른 구성 요소의 자리를 차지하는 작은 코드입니다.A stub is a small piece of code that takes the place of another component during testing. 스텁을 사용하는 이점은 일관적 결과를 반환하기 때문에 테스트를 더 쉽게 작성할 수 있다는 점입니다.The benefit of using a stub is that it returns consistent results, making the test easier to write. 또한 아직 다른 구성 요소가 작동하지 않을 경우에도 테스트를 실행할 수 있습니다.And you can run tests even if the other components are not working yet.

Fakes의 개요 및 빠른 시작 가이드를 보려면 Microsoft Fakes를 사용하여 테스트 대상 코드 격리를 참조하세요.For an overview and quick start guide to Fakes, see Isolating Code Under Test with Microsoft Fakes.

스텁을 사용하려면 클래스가 아닌 인터페이스만 사용하여 애플리케이션의 다른 부분을 참조하도록 구성 요소를 작성해야 합니다.To use stubs, you have to write your component so that it uses only interfaces, not classes, to refer to other parts of the application. 이 경우 한 부분을 변경하더라도 다른 부분을 변경해야 할 가능성이 적기 때문에 좋은 설계 습관입니다.This is a good design practice because it makes changes in one part less likely to require changes in another. 테스트를 위해 스텁을 실제 구성 요소로 대체할 수 있습니다.For testing, it allows you to substitute a stub for a real component.

다이어그램에서 StockAnalyzer 구성 요소가 테스트하려는 대상입니다.In the diagram, the component StockAnalyzer is the one we want to test. 이 구성 요소는 일반적으로 다른 구성 요소인 RealStockFeed를 사용합니다.It normally uses another component, RealStockFeed. 하지만 RealStockFeed는 해당 메서드가 호출될 때마다 다른 결과를 반환하기 때문에 StockAnalyzer를 테스트하기가 어렵습니다.But RealStockFeed returns different results every time its methods are called, making it difficult to test StockAnalyzer. 테스트하는 동안 StubStockFeed라는 다른 클래스로 대체하겠습니다.During testing, we replace it with a different class, StubStockFeed.

Real 및 Stub 클래스는 하나의 인터페이스를 준수합니다.Real and Stub classes conform to one interface.

스텁은 사용자가 이러한 방식으로 코드를 구성할 수 있어야 사용 가능하므로 일반적으로 응용 프로그램의 다른 부분에서 한 부분을 격리하는 데 사용합니다.Because stubs rely on your being able to structure your code in this way, you typically use stubs to isolate one part of your application from another. System.dll과 같이 사용자가 제어하지 않는 다른 어셈블리에서 일부를 격리하려면 일반적으로 shim을 사용합니다.To isolate it from other assemblies that are not under your control, such as System.dll, you would normally use shims. shim을 사용하여 유닛 테스트를 위한 다른 어셈블리에서 응용 프로그램 격리를 참조하세요.See Using shims to isolate your application from other assemblies for unit testing.

RequirementsRequirements

  • Visual Studio EnterpriseVisual Studio Enterprise

항목 내용In this topic

스텁 사용 방법How to use stubs

종속성 주입을 위한 디자인Design for dependency injection

스텁을 사용하려면 다른 구성 요소가 서로 종속되지 않도록 하고 인터페이스 정의에만 종속되도록 응용 프로그램을 설계해야 합니다.To use stubs, your application has to be designed so that the different components are not dependent on each other, but only dependent on interface definitions. 구성 요소는 컴파일 타임에 결합되지 않고, 런타임에 연결됩니다.Instead of being coupled at compile time, components are connected at run time. 이러한 패턴에서는 변경 내용이 구성 요소 경계를 넘어 전파되지 않으므로 견고하고 업데이트가 간편한 소프트웨어를 만들 수 있습니다.This pattern helps to make software that is robust and easy to update, because changes tend not to propagate across component boundaries. 스텁을 사용하지 않는 경우에도 다음을 권장합니다.We recommend following it even if you don't use stubs. 새 코드를 작성하는 경우 종속성 삽입 패턴을 따르는 것이 쉽습니다.If you are writing new code, it's easy to follow the dependency injection pattern. 기존 소프트웨어에 대한 테스트를 작성하는 경우 리팩터링해야 할 수 있습니다.If you are writing tests for existing software, you might have to refactor it. 실무적으로 어려운 경우에는 대신 shim을 사용해 보세요.If that would be impractical, you could consider using shims instead.

다이어그램의 흥미로운 예제로 이 토론을 시작하겠습니다.Let's start this discussion with a motivating example, the one in the diagram. StockAnalyzer 클래스는 주식 가격을 읽고 몇 가지 흥미로운 결과를 생성합니다.The class StockAnalyzer reads share prices and generates some interesting results. 여기에는 우리가 테스트하려는 몇 가지 공용 메서드가 있습니다.It has some public methods, which we want to test. 간단히 특정 주식의 현재 가격만 보고하는 간단한 메서드만 살펴보겠습니다.To keep things simple, let's just look at one of those methods, a very simple one that reports the current price of a particular share. 이 메서드의 단위 테스트를 작성하려고 합니다.We want to write a unit test of that method. 다음은 테스트의 첫 번째 초안입니다.Here's the first draft of a test:

[TestMethod]  
public void TestMethod1()  
{  
    // Arrange:  
    var analyzer = new StockAnalyzer();  
    // Act:  
    var result = analyzer.GetContosoPrice();  
    // Assert:  
    Assert.AreEqual(123, result); // Why 123?  
}  
<TestMethod()> Public Sub TestMethod1()  
    ' Arrange:  
    Dim analyzer = New StockAnalyzer()  
    ' Act:  
    Dim result = analyzer.GetContosoPrice()  
    ' Assert:  
    Assert.AreEqual(123, result) ' Why 123?  
End Sub  

이 테스트의 한 가지 문제는 바로 알 수 있습니다. 주식 가격이 달라지기 때문에 어설션은 일반적으로 실패합니다.One problem with this test is immediately obvious: share prices vary, and so the assertion will usually fail.

또 다른 문제는 StockAnalyzer에서 사용하는 StockFeed 구성 요소가 아직 개발 중이라는 점입니다.Another problem might be that the StockFeed component, which is used by the StockAnalyzer, is still under development. 테스트 중인 메서드의 첫 번째 코드 초안은 다음과 같습니다.Here's the first draft of the code of the method under test:

public int GetContosoPrice()  
{  
    var stockFeed = new StockFeed(); // NOT RECOMMENDED  
    return stockFeed.GetSharePrice("COOO");  
}  
Public Function GetContosoPrice()  
    Dim stockFeed = New StockFeed() ' NOT RECOMMENDED  
    Return stockFeed.GetSharePrice("COOO")  
End Function  

이 상태에서는 StockFeed 클래스에 대한 작업이 아직 완료되지 않았기 때문에 이 메서드가 컴파일되지 않거나 예외를 throw할 수 있습니다.As it stands, this method might not compile or might throw an exception because work on the StockFeed class is not yet complete.

인터페이스 삽입은 이러한 문제를 모두 해결합니다.Interface injection addresses both of these problems.

인터페이스 삽입은 다음과 같은 규칙을 적용합니다.Interface injection applies the following rule:

  • 응용 프로그램의 구성 요소 코드는 선언 또는 new 문에서 다른 구성 요소의 클래스를 명시적으로 참조하면 안 됩니다.The code of any component of your application should never explicitly refer to a class in another component, either in a declaration or in a new statement. 대신, 변수 및 매개 변수는 인터페이스를 사용하여 선언해야 합니다.Instead, variables and parameters should be declared with interfaces. 구성 요소 인스턴스는 구성 요소 컨테이너로만 만들 수 있습니다.Component instances should be created only by the component's container.

    이 경우 "구성 요소"란 함께 개발하고 업데이트하는 클래스 또는 클래스의 그룹을 의미합니다.By "component" in this case we mean a class, or a group of classes that you develop and update together. 일반적으로 구성 요소는 Visual Studio 프로젝트의 코드입니다.Typically, a component is the code in one Visual Studio project. 한 구성 요소 안에 있는 클래스는 동시에 업데이트되므로 결합을 해제하는 것은 그보다 중요하지 않습니다.It's less important to decouple classes within one component, because they are updated at the same time.

    또한 System.dll과 같이 비교적 안정적 플랫폼의 클래스에서 구성 요소를 분리하는 것도 그렇게 중요하지 않습니다.It is also not so important to decouple your components from the classes of a relatively stable platform such as System.dll. 이러한 모든 클래스의 인터페이스를 작성할 경우 코드가 복잡해집니다.Writing interfaces for all these classes would clutter your code.

    따라서 StockAnalyzer 코드는 다음과 같은 인터페이스로 StockFeed에서 연결을 해제하여 개선할 수 있습니다.The StockAnalyzer code can therefore be improved by decoupling it from the StockFeed by using an interface like this:

public interface IStockFeed  
{  
    int GetSharePrice(string company);  
}  

public class StockAnalyzer  
{  
    private IStockFeed stockFeed;  
    public Analyzer(IStockFeed feed)  
    {  
        stockFeed = feed;  
    }  
    public int GetContosoPrice()  
    {  
        return stockFeed.GetSharePrice("COOO");  
    }  
}  
Public Interface IStockFeed  
    Function GetSharePrice(company As String) As Integer  
End Interface  

Public Class StockAnalyzer  
    ' StockAnalyzer can be connected to any IStockFeed:  
    Private stockFeed As IStockFeed  
    Public Sub New(feed As IStockFeed)  
        stockFeed = feed  
    End Sub    
    Public Function GetContosoPrice()  
        Return stockFeed.GetSharePrice("COOO")  
    End Function  
End Class  

이 예제에서 StockAnalyzer는 생성될 때 IStockFeed의 구현으로 전달됩니다.In this example, StockAnalyzer is passed an implementation of an IStockFeed when it is constructed. 완성된 응용 프로그램에서 초기화 코드는 연결을 수행합니다.In the completed application, the initialization code would perform the connection:

analyzer = new StockAnalyzer(new StockFeed())  

이 연결을 수행하는 더 유연한 방법이 있습니다.There are more flexible ways of performing this connection. 예를 들어, StockAnalyzer는 다른 조건에서 IStockFeed의 다른 구현을 인스턴스화할 수 있는 팩터리 개체를 수용할 수 있습니다.For example, StockAnalyzer could accept a factory object that can instantiate different implementations of IStockFeed in different conditions.

스텁 생성Generate stubs

테스트하려는 클래스를 이 클래스가 사용하는 다른 구성 요소에서 분리했습니다.You've decoupled the class you want to test from the other components that it uses. 분리하면 응용 프로그램을 더 견고하고 유연하게 만들 수 있을 뿐만 아니라, 테스트 중인 구성 요소를 테스트 목적용 인터페이스의 스텁 구현에 연결할 수 있습니다.As well as making the application more robust and flexible, the decoupling allows you to connect the component under test to stub implementations of the interfaces for test purposes.

스텁을 일반적인 방법으로 클래스로 간단하게 작성할 수 있습니다.You could simply write the stubs as classes in the usual way. 하지만 Microsoft Fakes는 모든 테스트에 가장 적절한 스텁을 만들 수 있는 더욱 동적인 방법을 제공합니다.But Microsoft Fakes provides you with a more dynamic way to create the most appropriate stub for every test.

스텁을 사용하려면 우선 인터페이스 정의에서 스텁 유형을 만들어야 합니다.To use stubs, you must first generate stub types from the interface definitions.

Fakes 어셈블리 추가Adding a Fakes Assembly
  1. 솔루션 탐색기에서 단위 테스트 프로젝트의 참조를 확장합니다.In Solution Explorer, expand your unit test project's References.

    • Visual Basic에서 작업하는 경우 참조 목록을 보려면 솔루션 탐색기 도구 모음에서 모든 파일 표시를 선택해야 합니다.If you are working in Visual Basic, you must select Show All Files in the Solution Explorer toolbar, in order to see the References list.
  2. 스텁을 만들 인터페이스 정의가 포함된 어셈블리를 선택합니다.Select the assembly that contains the interface definitions for which you want to create stubs.

  3. 바로 가기 메뉴에서 Fakes 어셈블리 추가를 선택합니다.On the shortcut menu, choose Add Fakes Assembly.

스텁을 사용하여 테스트 작성Write your test with stubs

[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 클래스입니다.The special piece of magic here is the class StubIStockFeed. Microsoft Fakes는 참조된 어셈블리의 모든 공용 형식에 대해 스텁 클래스를 생성합니다.For every public type in the referenced assembly, the Microsoft Fakes mechanism generates a stub class. 스텁 클래스의 이름은 인터페이스의 이름에서 파생되며 "Fakes.Stub"가 접두사가 되고 매개 변수 형식 이름이 추가됩니다.The name of the stub class is the derived from the name of the interface, with "Fakes.Stub" as a prefix, and the parameter type names appended.

스텁은 속성, 이벤트 및 제네릭 메서드의 getter와 setter에 대해서도 생성됩니다.Stubs are also generated for the getters and setters of properties, for events, and for generic methods.

매개 변수 값 확인Verifying parameter values

구성 요소가 다른 구성 요소를 호출할 때 올바른 값을 전달하는지 확인할 수 있습니다.You can verify that when your component makes a call to another component, it passes the correct values. 스텁에 어설션을 추가하거나 값을 저장한 다음 테스트 본문에서 확인할 수 있습니다.You can either place an assertion in the stub, or you can store the value and verify it in the main body of the test. 예:For example:

[TestClass]  
class TestMyComponent  
{  

    [TestMethod]  
    public void TestVariableContosoPrice()  
    {  
     // Arrange:  
        int priceToReturn;  
        string companyCodeUsed;  
        var componentUnderTest = new StockAnalyzer(new StubIStockFeed()  
            {  
               GetSharePriceString = (company) =>   
                  {   
                     // Store the parameter value:  
                     companyCodeUsed = company;  
                     // Return the value prescribed by this test:  
                     return priceToReturn;  
                  };  
            };  
        // Set the value that will be returned by the stub:  
        priceToReturn = 345;  

     // Act:  
        int actualResult = componentUnderTest.GetContosoPrice();  

     // Assert:  
        // Verify the correct result in the usual way:  
        Assert.AreEqual(priceToReturn, actualResult);  

        // Verify that the component made the correct call:  
        Assert.AreEqual("COOO", companyCodeUsed);  
    }  
...}  
<TestClass()> _  
Class TestMyComponent  
    <TestMethod()> _  
    Public Sub TestVariableContosoPrice()  
        ' Arrange:  
        Dim priceToReturn As Integer  
        Dim companyCodeUsed As String = ""  
        Dim stockFeed As New StockAnalysis.Fakes.StubIStockFeed()  
        With stockFeed  
            ' Implement the interface's method:  
            .GetSharePriceString = _  
                Function(company)  
                    ' Store the parameter value:  
                    companyCodeUsed = company  
                    ' Return a fixed result:  
                    Return priceToReturn  
                End Function  
        End With  
        ' Create an object to test:  
        Dim componentUnderTest As New StockAnalyzer(stockFeed)  
        ' Set the value that will be returned by the stub:  
        priceToReturn = 345  

        ' Act:  
        Dim actualResult As Integer = componentUnderTest.GetContosoPrice()  

        ' Assert:  
        ' Verify the correct result in the usual way:  
        Assert.AreEqual(priceToReturn, actualResult)  
        ' Verify that the component made the correct call:  
        Assert.AreEqual("COOO", companyCodeUsed)  
    End Sub  
...  
End Class  

다양한 형식 멤버에 대한 스텁Stubs for different kinds of type members

메서드Methods

예제에서 설명한 대로, 대리자를 스텁 클래스 인스턴스에 연결하여 메서드를 스텁할 수 있습니다.As described in the example, methods can be stubbed by attaching a delegate to an instance of the stub class. 스텁 형식의 이름은 메서드 및 매개 변수 이름에서 파생됩니다.The name of the stub type is derived from the names of the method and parameters. 예를 들어, 다음 IMyInterface 인터페이스와 MyMethod 메서드가 있는 경우를 가정합니다.For example, given the following IMyInterface interface and method MyMethod:

// application under test  
interface IMyInterface   
{  
    int MyMethod(string value);  
}  

항상 1을 반환하는 MyMethod에 스텁을 연결합니다.We attach a stub to MyMethod that always returns 1:

// unit test code  
  var stub = new StubIMyInterface ();  
  stub.MyMethodString = (value) => 1;  

함수에 스텁을 제공하지 않으면 Fakes에서 반환 형식의 기본값을 반환하는 함수를 생성합니다.If you do not provide a stub for a function, Fakes will generate a function that returns the default value of the return type. 숫자의 경우 기본값은 0이며 클래스 형식의 경우 null(C#) 또는 Nothing(Visual Basic)입니다.For numbers, the default value is 0, and for class types it is null (C#) or Nothing (Visual Basic).

속성Properties

getter 및 setter 속성은 별도 대리자로 노출되고 별도로 스텁할 수 있습니다.Property getters and setters are exposed as separate delegates and can be stubbed separately. 예를 들어, ValueIMyInterface 속성을 고려합니다.For example, consider the Value property of IMyInterface:

// code under test  
interface IMyInterface   
{  
    int Value { get; set; }  
}  

자동 속성을 시뮬레이트하기 위해 Value의 getter 및 setter에 대리자를 연결합니다.We attach delegates to the getter and setter of Value to simulate an auto-property:

// unit test code  
int i = 5;  
var stub = new StubIMyInterface();  
stub.ValueGet = () => i;  
stub.ValueSet = (value) => i = value;  

속성의 setter 또는 getter에 스텁 메서드를 제공하지 않을 경우 스텁 속성이 간단한 변수처럼 작동하도록 Fakes에서 값을 저장하는 스텁을 생성합니다.If you do not provide stub methods for either the setter or the getter of a property, Fakes will generate a stub that stores values, so that the stub property works like a simple variable.

이벤트Events

이벤트는 대리자 필드로 노출됩니다.Events are exposed as delegate fields. 그 결과, 스텁된 이벤트는 이벤트 지원 필드만 호출하여 발생시킬 수 있습니다.As a result, any stubbed event can be raised simply by invoking the event backing field. 예를 들어, 스텁할 다음과 같은 인터페이스를 생각해 볼 수 있습니다.Let's consider the following interface to stub:

// code under test  
interface IWithEvents   
{  
    event EventHandler Changed;  
}  

Changed 이벤트를 발생시키려면 지원 대리자만 호출하면 됩니다.To raise the Changed event, we simply invoke the backing delegate:

// unit test code  
  var withEvents = new StubIWithEvents();  
  // raising Changed  
  withEvents.ChangedEvent(withEvents, EventArgs.Empty);  

제네릭 메서드Generic methods

메서드의 원하는 각 인스턴스화에 대한 대리자를 제공하여 제네릭 메서드를 스텁할 수 있습니다.It's possible to stub generic methods by providing a delegate for each desired instantiation of the method. 예를 들어, 제네릭 메서드가 포함된 다음 인터페이스가 있는 경우를 가정합니다.For example, given the following interface containing a generic method:

// code under test  
interface IGenericMethod   
{  
    T GetValue<T>();  
}  

GetValue<int> 인스턴스화를 스텁하는 테스트를 작성할 수 있습니다.you could write a test that stubs the GetValue<int> instantiation:

// unit test code  
[TestMethod]  
public void TestGetValue()   
{  
    var stub = new StubIGenericMethod();  
    stub.GetValueOf1<int>(() => 5);  

    IGenericMethod target = stub;  
    Assert.AreEqual(5, target.GetValue<int>());  
}  

코드가 기타 인스턴스화를 사용하여 GetValue<T>를 호출하는 경우 스텁이 동작만 호출합니다.If the code were to call GetValue<T> with any other instantiation, the stub would simply call the behavior.

가상 클래스의 스텁Stubs of virtual classes

위 예제에서는 인터페이스에서 스텁이 생성되었습니다.In the previous examples, the stubs have been generated from interfaces. 또한 가상 또는 추상 멤버가 있는 클래스에서 스텁을 생성할 수 있습니다.You can also generate stubs from a class that has virtual or abstract members. 예를 들면 다음과 같습니다.For example:

// Base class in application under test  
    public abstract class MyClass  
    {  
        public abstract void DoAbstract(string x);  
        public virtual int DoVirtual(int n)  
        { return n + 42; }  
        public int DoConcrete()  
        { return 1; }  
    }  

이 클래스에서 생성한 스텁에서, DoAbstract() 및 DoVirtual()에 대한 대리자를 설정할 수 있지만 DoConcrete()에 대한 대리자는 설정할 수 없습니다.In the stub generated from this class, you can set delegate methods for DoAbstract() and DoVirtual(), but not DoConcrete().

// unit test  
  var stub = new Fakes.MyClass();  
  stub.DoAbstractString = (x) => { Assert.IsTrue(x>0); };  
  stub.DoVirtualInt32 = (n) => 10 ;  

가상 메서드에 대한 대리자를 제공하지 않는 경우 Fakes는 기본 동작을 제공하거나 기본 클래스의 메서드를 호출할 수 있습니다.If you do not provide a delegate for a virtual method, Fakes can either provide the default behavior, or it can call the method in the base class. 기본 메서드를 호출하려면 CallBase 속성을 설정합니다.To have the base method called, set the CallBase property:

// unit test code  
var stub = new Fakes.MyClass();  
stub.CallBase = false;  
// No delegate set - default delegate:  
Assert.AreEqual(0, stub.DoVirtual(1));  

stub.CallBase = true;  
//No delegate set - calls the base:  
Assert.AreEqual(43,stub.DoVirtual(1));  

스텁 디버그Debugging stubs

스텁 형식은 부드러운 디버깅 환경을 제공하도록 설계되었습니다.The stub types are designed to provide a smooth debugging experience. 기본적으로 디버거는 생성된 코드를 건너뛰도록 지정되어 있으므로 스텁에 연결된 사용자 지정 멤버 구현으로 직접 건너뜁니다.By default, the debugger is instructed to step over any generated code, so it should step directly into the custom member implementations that were attached to the stub.

스텁 제한Stub limitations

  1. 포인터가 포함된 메서드 시그니처는 지원되지 않습니다.Method signatures with pointers aren't supported.

  2. 스텁 형식은 가상 메서드 디스패치에 의존하므로 봉인 클래스 또는 정적 메서드는 스텁할 수 없습니다.Sealed classes or static methods can't be stubbed because stub types rely on virtual method dispatch. 이러한 경우 shim을 사용하여 유닛 테스트를 위한 다른 어셈블리에서 응용 프로그램 격리에서 설명한 대로 shim 형식을 사용합니다.For such cases, use shim types as described in Using shims to isolate your application from other assemblies for unit testing

스텁의 기본 동작 변경Changing the default behavior of stubs

생성된 각 스텁 유형에는 IStubBehavior 인터페이스의 인스턴스가 포함됩니다(IStub.InstanceBehavior 속성을 통해).Each generated stub type holds an instance of the IStubBehavior interface (through the IStub.InstanceBehavior property). 이 동작은 클라이언트가 사용자 지정 대리자가 연결되지 않은 멤버를 호출할 때마다 호출됩니다.The behavior is called whenever a client calls a member with no attached custom delegate. 동작이 설정되지 않은 경우 StubsBehaviors.Current 속성에서 반환한 인스턴스를 사용합니다.If the behavior has not been set, it will use the instance returned by the StubsBehaviors.Current property. 기본적으로 이 속성은 NotImplementedException 예외를 throw하는 동작을 반환합니다.By default, this property returns a behavior that throws a NotImplementedException exception.

이 동작은 스텁 인스턴스의 InstanceBehavior 속성을 설정하여 언제든지 변경할 수 있습니다.The behavior can be changed at any time by setting the InstanceBehavior property on any stub instance. 예를 들어, 다음 코드 조각은 아무 작업을 하지 않거나 반환 형식의 기본 값 default(T)를 반환하는 동작을 변경합니다.For example, the following snippet changes a behavior that does nothing or returns the default value of the return type: default(T):

// unit test code  
var stub = new StubIFileSystem();  
// return default(T) or do nothing  
stub.InstanceBehavior = StubsBehaviors.DefaultValue;  

이 동작은 또한 StubsBehaviors.Current 속성을 설정하여 동작을 설정하지 않은 모든 스텁 개체에 대해 전역적으로 변경할 수 있습니다.The behavior can also be changed globally for all stub objects for which the behavior has not been set by setting the StubsBehaviors.Current property:

// unit test code  
//change default behavior for all stub instances  
//where the behavior has not been set  
StubBehaviors.Current =   
    BehavedBehaviors.DefaultValue;  

외부 리소스External resources

지침Guidance

Visual Studio 2012를 사용한 지속적인 업데이트 테스트 - 2장: 유닛 테스트: 내부 테스트Testing for Continuous Delivery with Visual Studio 2012 - Chapter 2: Unit Testing: Testing the Inside

참고 항목See Also

Microsoft Fakes를 사용하여 테스트 중인 코드 격리Isolating Code Under Test with Microsoft Fakes