それについて2つの方法はありません。ReSharperの提案とC#のいくつかの便利な機能は、すべてのコードに対して分離されたアトミックユニットテストを作成する場合ほど頻繁には使用されません。
たとえば、静的メソッドがあり、それをスタブ化する必要がある場合、プロファイルベースの分離フレームワークを使用しない限りできません。呼び出し互換の回避策は、ラムダ表記を使用するようにメソッドの上部を変更することです。例えば:
前:
public static DBConnection ConnectToDB( string dbName, string connectionInfo ) {
}
後:
public static Func<string, string, DBConnection> ConnectToDB (dbName, connectionInfo ) {
};
2つは呼び出し互換です。発信者は変更する必要はありません。関数の本体は同じままです。
次に、Unit-Testコードで、この呼び出しを次のようにスタブできます(Databaseと呼ばれるクラスにあると仮定します):
Database.ConnectToDB = (dbName, connectionInfo) => { return null|whatever; }
完了したら、元の値に置き換えてください。try / finallyを介してそれを行うことができます。または、ユニットテストのクリーンアップで、各テストの後に呼び出されるクリーンアップで、次のようなコードを記述します。
[TestCleanup]
public void Cleanup()
{
typeof(Database).TypeInitializer.Invoke(null, null);
}
これにより、クラスの静的初期化子が再度呼び出されます。
Lambda Funcsは通常の静的メソッドほどサポートが充実していないため、このアプローチには次の望ましくない副作用があります。
- 静的メソッドが拡張メソッドであった場合、最初に非拡張メソッドに変更する必要があります。Resharperはこれを自動的に行います。
- 静的メソッドのデータ型のいずれかがOfficeなどの埋め込み相互運用アセンブリである場合、メソッドをラップするか、タイプをラップするか、「オブジェクト」タイプに変更する必要があります。
- Resharperの変更署名リファクタリングツールは使用できなくなりました。
しかし、静的を完全に回避し、これをインスタンスメソッドに変換するとします。メソッドが仮想であるか、インターフェイスの一部として実装されていない限り、まだモック化できません。
したがって、実際には、静的メソッドをスタブ化するための解決策を提案する人は、それらをインスタンスメソッドにすることであり、仮想またはインターフェイスの一部ではないインスタンスメソッドに対してもなります。
では、C#に静的メソッドがあるのはなぜですか?なぜ非仮想インスタンスメソッドを許可するのですか?
これらの「機能」のいずれかを使用する場合、分離メソッドを作成することはできません。
それで、いつそれらを使いますか?
誰もスタブアウトしたくないと思われるコードに使用してください。いくつかの例:StringクラスのFormat()メソッド、ConsoleクラスのWriteLine()メソッド、MathクラスのCosh()メソッド
そしてもう1つ..ほとんどの人はこれを気にしませんが、間接呼び出しのパフォーマンスについては、インスタンスメソッドを避けるもう1つの理由です。パフォーマンスが低下する場合があります。そのため、そもそも非仮想メソッドが存在します。