shim を使用して単体テストでアプリケーションを他のアセンブリから分離するUsing shims to isolate your application from other assemblies for unit testing

Shim 型は、テスト中のコンポーネントを環境から簡単に分離するために Microsoft Fakes Framework が使用する 2 つのテクノロジのうちの 1 つです。Shim types are one of two technologies that the Microsoft Fakes Framework uses to let you easily isolate components under test from the environment. Shim は、特定のメソッドの呼び出しを、テストの一部として作成したコードに迂回させます。Shims divert calls to specific methods to code that you write as part of your test. 多くのメソッドは、外部の状況に応じて異なる結果を返しますが、shim はテストの制御下にあり、すべての呼び出しで一定の結果を返すことができます。Many methods return different results dependent on external conditions, but a shim is under the control of your test and can return consistent results at every call. そのため、テストの記述が非常に簡単になります。This makes your tests much easier to write.

shim を使用して、ソリューションの一部ではないアセンブリからコードを分離します。Use shims to isolate your code from assemblies that are not part of your solution. ソリューションの各コンポーネントを分離するには、スタブを使用することをお勧めします。To isolate components of your solution from each other, we recommend that you use stubs.

概要とクイック スタート ガイドについては、「Microsoft Fakes を使用したテストでのコードの分離」を参照してください。For an overview and quick start guidance, see Isolating Code Under Test with Microsoft Fakes

RequirementsRequirements

このトピックの内容In this topic

このトピックで学習する内容は、次のとおりです。Here's what you'll learn in this topic:

例: Y2K バグExample: The Y2K bug

Shim の使用方法How to use Shims

例: Y2K バグExample: The Y2K bug

2000 年 1 月 1 日に例外をスローするメソッドについて考えてみましょう。Let's consider a method that throws an exception on January 1st of 2000:

// code under test  
public static class Y2KChecker {  
    public static void Check() {  
        if (DateTime.Now == new DateTime(2000, 1, 1))  
            throw new ApplicationException("y2kbug!");  
    }  
}  

このメソッドのテストが特に難しいのは、プログラムが DateTime.Now メソッドに依存しているためです。このメソッドは、コンピューターのクロックに依存する、環境依存の非確定的なメソッドです。Testing this method is particularly problematic because the program depends on DateTime.Now, a method that depends on the computer's clock, an environment-dependent, non-deterministic method. さらに、DateTime.Now は静的なプロパティであるため、ここではスタブ型を使用できません。Furthermore, the DateTime.Now is a static property so a stub type can't be used here. この問題は、単体テストで分離の問題があることを示します。直接データベース API を呼び出したり、Web サービスと通信したりするプログラムは、単体テストを行うことが困難です。それらのロジックが環境に依存するためです。This problem is symptomatic of the isolation issue in unit testing: programs that directly call into database APIs, communicate with web services, and so on are hard to unit test because their logic depends on the environment.

そこで、shim 型を使用する必要があります。This is where shim types should be used. shim 型には、任意の .NET メソッドをユーザー定義のデリゲートに迂回させるしくみがあります。Shim types provide a mechanism to detour any .NET method to a user defined delegate. shim 型は Fakes ジェネレーターによってコード生成され、新しいメソッドの実装を指定するために、shim 型と呼ばれるデリゲートを使用します。Shim types are code-generated by the Fakes generator, and they use delegates, which we call shim types, to specify the new method implementations.

次のテストは、ShimDateTime という shim 型を使用して DateTime.Now のカスタム実装を提供する方法を示しています。The following test shows how to use the shim type, ShimDateTime, to provide a custom implementation of DateTime.Now:

//unit test code  
// create a ShimsContext cleans up shims   
using (ShimsContext.Create()  
    // hook delegate to the shim method to redirect DateTime.Now  
    // to return January 1st of 2000  
    ShimDateTime.NowGet = () => new DateTime(2000, 1, 1);  
    Y2KChecker.Check();  
}  

Shim の使用方法How to use Shims

Fakes アセンブリを追加するAdd Fakes Assemblies

  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. 作成する shim に対応するクラス定義が含まれているアセンブリを選択します。Select the assembly that contains the classes definitions for which you want to create shims. たとえば、shim が DateTime の場合は、System.dll を選択します。For example, if you want to shim DateTime, select System.dll

  3. ショートカット メニューで、[Fakes アセンブリに追加] を選択します。On the shortcut menu, choose Add Fakes Assembly.

ShimsContext を使用するUse ShimsContext

単体テスト フレームワークで shim 型を使用する場合は、shim の有効期間を制御するために、テスト コードを ShimsContext でラップする必要があります。When using shim types in a unit test framework, you must wrap the test code in a ShimsContext to control the lifetime of your shims. そうしなかった場合、shim は AppDomain のシャットダウンまで存続します。If we didn't require this, your shims would last until the AppDomain shut down. ShimsContext を作成するための最も簡単な方法は、次のコードに示すように、静的な Create() メソッドを使用することです。The easiest way to create a ShimsContext is by using the static Create() method as shown in the following code:

//unit test code  
[Test]  
public void Y2kCheckerTest() {  
  using(ShimsContext.Create()) {  
    ...  
  } // clear all shims  
}  

各 shim コンテキストを適切に破棄することが重要です。It is critical to properly dispose each shim context. 原則としては、登録した shim を適切に消去するために、常に using ステートメント内で ShimsContext.Create を呼び出します。As a rule of thumb, always call the ShimsContext.Create inside of a using statement to ensure proper clearing of the registered shims. たとえば、DateTime.Now メソッドを常に 2000 年 1 月 1 日を返すデリゲートに置き換えるテスト メソッドのために shim を登録する場合があります。For example, you might register a shim for a test method that replaces the DateTime.Now method with a delegate that always returns the first of January 2000. テスト メソッド内で登録済み shim を消去し忘れた場合、テスト実行の残りの部分では、DateTime.Now 値として常に 2000 年 1 月 1 日が返されます。If you forget to clear the registered shim in the test method, the rest of the test run would always return the first of January 2000 as the DateTime.Now value. これは、予想外で、混乱を招く可能性があります。This might be suprising and confusing.

shim を使用してテストを作成するWrite a test with shims

テスト コード内で、フェイク メソッドに detour を挿入します。In your test code, insert a detour for the method you want to fake. 例:For example:

[TestClass]  
public class TestClass1  
{   
        [TestMethod]  
        public void TestCurrentYear()  
        {  
            int fixedYear = 2000;  

            using (ShimsContext.Create())  
            {  
              // Arrange:  
                // Detour 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 class names are made up by prefixing Fakes.Shim to the original type name.

shim は、テスト対象のアプリケーションのコードに detours を挿入することによって機能します。Shims work by inserting detours into the code of the application under test. 元のメソッドへの呼び出しがどこで行われても、Fakes システムによって迂回され、実際のメソッドではなく shim コードが呼び出されます。Wherever a call to the original method occurs, the Fakes system performs a detour, so that instead of calling the real method, your shim code is called.

迂回の作成と削除は実行時に行われる点に注意してください。Notice that detours are created and deleted at run time. 常に ShimsContext の有効期間内で迂回を作成する必要があります。You must always create a detour within the life of a ShimsContext. これを破棄すると、これがアクティブなときに作成したすべての shim が削除されます。When it is disposed, any shims you created while it was active are removed. このようにするための最善の方法は、using ステートメントの内部で対処することです。The best way to do this is inside a using statement.

Fakes 名前空間が存在しないことを示すビルド エラーが表示される場合があります。You might see a build error stating that the Fakes namespace does not exist. このエラーは、他のコンパイル エラーがあるときに表示されることがあります。This error sometimes appears when there are other compilation errors. 他のエラーを修正すると、表示されなくなります。Fix the other errors and it will vanish.

さまざまな種類のメソッドの shimShims for different kinds of methods

shim 型では、任意の .NET メソッド (静的メソッドまたは非仮想メソッドを含む) を独自のデリゲートに置き換えることができます。Shim types allow you to replace any .NET method, including static methods or non-virtual methods, with your own delegates.

静的メソッドStatic methods

shim を静的メソッドにアタッチするプロパティは、shim 型に備わっています。The properties to attach shims to static methods are placed in a shim type. 各プロパティには、デリゲートを対象のメソッドにアタッチするために使用されるセッターだけが存在します。Each property has only a setter that can be used to attach a delegate to the target method. たとえば、クラス MyClass に静的メソッド MyMethod があるとします。For example, given a class MyClass with a static method MyMethod:

//code under test  
public static class MyClass {  
    public static int MyMethod() {  
        ...  
    }  
}  

常に 5 を返す MyMethod に shim をアタッチできます。We can attach a shim to MyMethod that always returns 5:

// unit test code  
ShimMyClass.MyMethod = () =>5;  

インスタンス メソッド (すべてのインスタンス用)Instance methods (for all instances)

静的メソッドと同様に、インスタンス メソッドはすべてのインスタンスに対して shim を適用できます。Similarly to static methods, instance methods can be shimmed for all instances. これらの shim をアタッチするプロパティは、混乱を避けるために、AllInstances という名前の、入れ子になった型に配置されます。The properties to attach those shims are placed in a nested type named AllInstances to avoid confusion. たとえば、クラス MyClass にインスタンス メソッド MyMethod があるとします。For example, given a class MyClass with an instance method MyMethod:

// code under test  
public class MyClass {  
    public int MyMethod() {  
        ...  
    }  
}  

どのインスタンスかにかかわらず、常に 5 を返す MyMethod に shim をアタッチできます。You can attach a shim to MyMethod that always returns 5, regardless of the instance:

// unit test code  
ShimMyClass.AllInstances.MyMethod = () => 5;  

ShimMyClass の生成された型の構造は、次のコードのようになります。The generated type structure of ShimMyClass looks like the following code:

// Fakes generated code  
public class ShimMyClass : ShimBase<MyClass> {  
    public static class AllInstances {  
        public static Func<MyClass, int>MyMethod {  
            set {  
                ...  
            }  
        }  
    }  
}  

この場合、Fakes によって実行時インスタンスがデリゲートの第 1 引数として渡されることに注意してください。Notice that Fakes passes the runtime instance as the first argument of the delegate in this case.

インスタンス メソッド (1 つの実行時インスタンス用)Instance methods (for one runtime instance)

インスタンス メソッドには、呼び出しのレシーバーに応じて異なるデリゲートによって shim を適用することもできます。Instance methods can also be shimmed by different delegates, based on the receiver of the call. そうすることで、同じインスタンス メソッドに、インスタンスの型に応じて異なる動作をさせることができます。This enables the same instance method to have different behaviors per instance of the type. これらの shim を設定するプロパティは、shim 型自体のインスタンス メソッドです。The properties to set up those shims are instance methods of the shim type itself. インスタンス化された各 shim 型も、shim が適用された型の生のインスタンスに関連付けられます。Each instantiated shim type is also associated with a raw instance of a shimmed type.

たとえば、クラス MyClass にインスタンス メソッド MyMethod があるとします。For example, given a class MyClass with an instance method MyMethod:

// code under test  
public class MyClass {  
    public int MyMethod() {  
        ...  
    }  
}  

MyMethod には 2 つの shim 型をセットアップし、1 つ目は常に 5 を返し、2 つ目は常に 10 を返すようにすることができます。We can set up two shim types of MyMethod such that the first one always returns 5 and the second always returns 10:

// unit test code  
var myClass1 = new ShimMyClass()  
{  
    MyMethod = () => 5  
};  
var myClass2 = new ShimMyClass { MyMethod = () => 10 };  

ShimMyClass の生成された型の構造は、次のコードのようになります。The generated type structure of ShimMyClass looks like the following code:

// Fakes generated code  
public class ShimMyClass : ShimBase<MyClass> {  
    public Func<int> MyMethod {  
        set {  
            ...  
        }  
    }  
    public MyClass Instance {  
        get {  
            ...  
        }  
    }  
}  

shim が適用された実際の型のインスタンスには、Instance プロパティを通じてアクセスできます。The actual shimmed type instance can be accessed through the Instance property:

// unit test code  
var shim = new ShimMyClass();  
var instance = shim.Instance;  

shim 型では、shim が適用された型への暗黙的な変換も行われるため、通常は shim 型を単純にそのまま使用できます。The shim type also has an implicit conversion to the shimmed type, so you can usually simply use the shim type as is:

// unit test code  
var shim = new ShimMyClass();  
MyClass instance = shim; // implicit cast retrieves the runtime  
                         // instance  

コンストラクターConstructors

shim 型を将来的なオブジェクトにアタッチするために、コンストラクターにも shim を適用できます。Constructors can also be shimmed in order to attach shim types to future objects. 各コンストラクターは、shim 型の静的メソッド Constructor として公開されます。Each constructor is exposed as a static method Constructor in the shim type. たとえば、コンストラクターが整数を受け取るクラス MyClass があるとします。For example, given a class MyClass with a constructor taking an integer:

// code under test  
public class MyClass {  
    public MyClass(int value) {  
        this.Value = value;  
    }  
    ...  
}  

値ゲッターが呼び出されたときに、コンストラクター内の値にかかわらず、将来的なすべてのインスタンスが -5 を返すように、コンストラクターの shim 型をセットアップします。We set up the shim type of the constructor so that every future instance returns -5 when the Value getter is invoked, regardless of the value in the constructor:

// unit test code  
ShimMyClass.ConstructorInt32 = (@this, value) => {  
    var shim = new ShimMyClass(@this) {  
        ValueGet = () => -5  
    };  
};  

各 shim 型は 2 つのコンストラクターを公開することに注意してください。Note that each shim type exposes two constructors. 新規のインスタンスが必要な場合には既定のコンストラクターを使用し、shim のみのコンストラクターでは shim が適用されたインスタンスを引数として受け取るコンストラクターを使用する必要があります。The default constructor should be used when a fresh instance is needed, while the constructor taking a shimmed instance as argument should be used in constructor shims only:

// unit test code  
public ShimMyClass() { }  
public ShimMyClass(MyClass instance) : base(instance) { }  

ShimMyClass の生成された型の構造は、次のコードのようになります。The generated type structure of ShimMyClass resembles the followoing code:

// Fakes generated code  
public class ShimMyClass : ShimBase<MyClass>  
{  
    public static Action<MyClass, int> ConstructorInt32 {  
        set {  
            ...  
        }  
    }  

    public ShimMyClass() { }  
    public ShimMyClass(MyClass instance) : base(instance) { }  
    ...  
}  

基本メンバーBase members

基本メンバーの shim プロパティにアクセスするには、基本型の shim を作成し、基本 shim クラスのコンストラクターへのパラメーターとして子インスタンスを渡します。The shim properties of base members can be accessed by creating a shim for the base type and passing the child instance as a parameter to the constructor of the base shim class.

たとえば、クラス MyBase にインスタンス メソッド MyMethod とサブタイプ MyChild があるとします。For example, given a class MyBase with an instance method MyMethod and a subtype MyChild:

public abstract class MyBase {  
    public int MyMethod() {  
        ...  
    }  
}  

public class MyChild : MyBase {  
}  

MyBase の shim をセットアップするには、新しい ShimMyBase shim を作成します。We can set up a shim of MyBase by creating a new ShimMyBase shim:

// unit test code  
var child = new ShimMyChild();  
new ShimMyBase(child) { MyMethod = () => 5 };  

子 shim 型は、基本 shim コンストラクターにパラメーターとして渡されるときに、暗黙的に子インスタンスに変換されることに注意してください。Note that the child shim type is implicitly converted to the child instance when passed as a parameter to the base shim constructor.

ShimMyChild と ShimMyBase の生成された型の構造は、次のコードのようになります。The generated type structure of ShimMyChild and ShimMyBase resembles the following code:

// Fakes generated code  
public class ShimMyChild : ShimBase<MyChild> {  
    public ShimMyChild() { }  
    public ShimMyChild(Child child)  
        : base(child) { }  
}  
public class ShimMyBase : ShimBase<MyBase> {  
    public ShimMyBase(Base target) { }  
    public Func<int> MyMethod  
    { set { ... } }  
}  

静的コンストラクターStatic constructors

shim 型は、型の静的コンストラクターに shim を適用するために、静的メソッド StaticConstructor を公開します。Shim types expose a static method StaticConstructor to shim the static constructor of a type. 静的コンストラクターは 1 回だけ実行されるため、型のいずれかのメンバーがアクセスされる前に shim が構成されることを確認する必要があります。Since static constructors are executed once only, you need to ensure that the shim is configured before any member of the type is accessed.

ファイナライザーFinalizers

ファイナライザーは、Fakes ではサポートされません。Finalizers are not supported in Fakes.

プライベート メソッドPrivate methods

Fakes コード ジェネレーターは、シグネチャに参照可能な型だけを持つプライベート メソッドの shim プロパティを作成します。つまり、パラメーターの型と戻り値の型が参照可能です。The Fakes code generator will create shim properties for private methods that only have visible types in the signature, i.e. parameter types and return type visible.

バインド インターフェイスBinding interfaces

shim が適用された型がインターフェイスを実装する場合、コード ジェネレーターは、そのインターフェイスのすべてのメンバーを一度にバインドできるメソッドを生成します。When a shimmed type implements an interface, the code generator emits a method that allows it to bind all the members from that interface at once.

たとえば、IEnumerable<int> を実装する MyClass クラスがあるとします。For example, given a class MyClass that implements IEnumerable<int>:

public class MyClass : IEnumerable<int> {  
    public IEnumerator<int> GetEnumerator() {  
        ...  
    }  
    ...  
}  

Bind メソッドを呼び出すことで、MyClass の IEnumerable<int> の実装に shim を適用できます。We can shim the implementations of IEnumerable<int> in MyClass by calling the Bind method:

// unit test code  
var shimMyClass = new ShimMyClass();  
shimMyClass.Bind(new List<int> { 1, 2, 3 });  

ShimMyClass の生成された型の構造は、次のコードのようになります。The generated type structure of ShimMyClass resembles the following code:

// Fakes generated code  
public class ShimMyClass : ShimBase<MyClass> {  
    public ShimMyClass Bind(IEnumerable<int> target) {  
        ...  
    }  
}  

既定の動作を変更するChanging the default behavior

生成された各 shim 型は、ShimBase<T>.InstanceBehavior プロパティを通じて、IShimBehavior インターフェイスのインスタンスを保持します。Each generated shim type holds an instance of the IShimBehavior interface, through the ShimBase<T>.InstanceBehavior property. 明示的に shim が適用されていないインスタンス メンバーをクライアントが呼び出すたびに、この動作が使用されます。The behavior is used whenever a client calls an instance member that was not explicitly shimmed.

この動作が明示的に設定されていない場合は、静的な ShimsBehaviors.Current プロパティによって返されるインスタンスが使用されます。If the behavior has not been explicitly set, it will use the instance returned by the static ShimsBehaviors.Current property. 既定では、このプロパティは NotImplementedException 例外をスローする動作を返します。By default, this property returns a behavior that throws a NotImplementedException exception.

この動作は、任意の shim インスタンスの InstanceBehavior プロパティを設定することによって、いつでも変更できます。This behavior can be changed at any time by setting the InstanceBehavior property on any shim instance. たとえば、次のスニペットは、何も行わないか、戻り値の型の既定値 (default(T)) を返す動作の shim を変更します。For example, the following snippet changes the shim to a behavior that does nothing or returns the default value of the return type—that is, default(T):

// unit test code  
var shim = new ShimMyClass();  
//return default(T) or do nothing  
shim.InstanceBehavior = ShimsBehaviors.DefaultValue;  

静的 ShimsBehaviors.Current プロパティを設定することによって InstanceBehavior プロパティが明示的に設定されていない、shim が適用されているすべてのインスタンスの動作を、グローバルに変更することもできます。The behavior can also be changed globally for all shimmed instances for which the InstanceBehavior property was not explicitly set by setting the static ShimsBehaviors.Current property:

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

環境アクセスの検出Detecting environment accesses

ShimsBehaviors.NotImplemented 動作を、対応する shim 型の静的プロパティ Behavior に割り当てることによって、特定の型のすべてのメンバー (静的メソッドも含む) に動作をアタッチすることができます。It is possible to attach a behavior to all the members, including static methods, of a particular type by assigning the ShimsBehaviors.NotImplemented behavior to the static property Behavior of the corresponding shim type:

// unit test code  
// assigning the not implemented behavior  
ShimMyClass.Behavior = ShimsBehaviors.NotImplemented;  
// shorthand  
ShimMyClass.BehaveAsNotImplemented();  

同時実行Concurrency

shim 型は、AppDomain のすべてのスレッドに適用され、スレッド アフィニティを持ちません。Shim types apply to all threads in the AppDomain and don't have thread affinity. 同時実行をサポートしているテスト ランナーを使用する予定の場合、これは重要な事実です。shim 型を含む複数のテストを同時に実行することはできません。This is an important fact if you plan to use a test runner that support concurrency: tests involving shim types cannot run concurrently. このプロパティが Fakes ランタイムによって強制されることはありません。This property is not enfored by the Fakes runtime.

shim メソッドからの元のメソッドの呼び出しCalling the original method from the shim method

メソッドに渡されたファイル名を検証した後で、実際にファイル システムにテキストを書き込む場合を想像してみてください。Imagine that we wanted to actually write the text to the file system after validating the file name passed to the method. この場合、shim メソッドの途中で元のメソッドを呼び出したいと思うでしょう。In that case, we would want to call the original method in the middle of the shim method.

この問題を解決するための 1 つ目の方法は、次のコードのように、デリゲートと ShimsContext.ExecuteWithoutShims() を使用して元のメソッドへの呼び出しをラップすることです。The first approach to solve this problem is to wrap a call to the original method using a delegate and ShimsContext.ExecuteWithoutShims() as in the following code:

// unit test code  
ShimFile.WriteAllTextStringString = (fileName, content) => {  
  ShimsContext.ExecuteWithoutShims(() => {  

      Console.WriteLine("enter");  
      File.WriteAllText(fileName, content);  
      Console.WriteLine("leave");  
  });  
};  

もう 1 つの方法は、shim を null に設定して元のメソッドを呼び出し、shim を復元することです。Another approach is to set the shim to null, call the original method and restore the shim.

// unit test code  
ShimsDelegates.Action<string, string> shim = null;  
shim = (fileName, content) => {  
  try {  
    Console.WriteLine("enter");  
    // remove shim in order to call original method  
    ShimFile.WriteAllTextStringString = null;  
    File.WriteAllText(fileName, content);  
  }  
  finally  
  {  
    // restore shim  
    ShimFile.WriteAllTextStringString = shim;  
    Console.WriteLine("leave");  
  }  
};  
// initialize the shim  
ShimFile.WriteAllTextStringString = shim;  

制限事項Limitations

shim は、.NET 基本クラス ライブラリ mscorlib および System のすべての型で使用できるわけではありません。Shims cannot be used on all types from the .NET base class library mscorlib and System.

外部リソース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
Peter Provost のブログ: Visual Studio 2012 の shim Peter Provost's blog: Visual Studio 2012 Shims
1 時間 16 分の動画: Testing Un-testable Code with Fakes in Visual Studio 2012 (Visual Studio 2012 で Fakes を利用し、テスト不可能なコードをテストする)Video (1h16): Testing Un-testable Code with Fakes in Visual Studio 2012