1

次のようなコードの単体テストを作成しようとしています。

foreach (string domainName in Directory.GetDirectories(server.Path))
{
     HandleDomainDirectory(session, server, domainName);
}

問題はSystem.IO.Directory、コードでクラスを使用していることです。ハードディスク上のどのフォルダにも依存しないテスト メソッドを作成するにはどうすればよいですか。つまり、「 」の応答を偽造するにはどうすればよいDirectory.GetDirectories(server.Path)でしょうか。(注意してください、私は自分のクラスで「サーバー」オブジェクトを制御しているため、必要なパスを指定できます)

ありがとう。

4

4 に答える 4

2

直接呼び出すのではなく、パス文字列を受け取り、ディレクトリのリストを返す単一のメソッドのDirectory.GetDirectories(server.Path)ようなインターフェイスを作成できます。IDirectoryResolver上記のコードを含むクラスにはIDirectoryResolver、コンストラクターまたはセッターを介して注入できるタイプのプロパティまたはフィールドが必要になります。

次に、本番コードの場合、インターフェイスを実装する新しいクラスを作成しIDirectoryResolverます。このクラスはDirectory.GetDirectories、インターフェイスメソッドの実装でメソッドを使用できます。

単体テストでは、MockDirectoryResolver実装するクラスを作成できますIDirectoryResolver(または、モックライブラリを使用してインターフェイスのモックインスタンスを作成できます)。模擬実装は、必要なことは何でも実行できます。

于 2011-04-18T20:57:01.477 に答える
1

ラッパークラスを挿入します。

public class DirectoryFetcher
{
     public virtual List<string> GetDirectoriesIn(string directory)
     {
          return Directory.GetDirectories(directory);
     }
}

そしてそれを注入します:

foreach(string directory in _directoryFetcher.GetDirectoriesIn(server.Path))
{
    // Whatever
}

次に、インジェクションポイントでその男をモックできます(この例ではMoqとコンストラクターインジェクションを使用します)。

Mock<DirectoryFetcher> mockFetcher = new Mock<DirectoryFetcher>();

mockFetcher.Setup(x => x.GetDirectoriesIn("SomeDirectory")).Returns(new List<string>
{
    "SampleDirectory1",
    "SampleDirectory2"
});

MyObjectToTest testObj = new MyObjectToTest(mockFetcher.Object);

// Do Test
于 2011-04-18T20:56:30.623 に答える
0

ファイル システム、データベース、Web サービスなど、外の世界と通信するときは、私が提案する前に、他のようなラッパー クラスを使用することを常に検討する必要があります。テスト容易性は主要な論拠の 1 つですが、さらに重要な論点は次のとおりです。外部の世界は変化し、それを制御することはできません。フォルダが移動し、ユーザー権限が変更され、新しいディスク ドライブが表示され、古いディスク ドライブが削除されます。そのようなことを一箇所で気にしたいだけです。したがって、ラッパー-Andy Whiteが以前に提案したように、DirectoryResolverと呼びましょう。

したがって、ファイル システム呼び出しをラップし、インターフェイスを抽出して、ファイル システムと通信する必要がある場所にそのインターフェイスを挿入します。

于 2011-04-19T07:01:57.520 に答える
0

私が見つけた最善の解決策は、Molesを使用することでした。コードは非常に具体的であり、非常に具体的なことを行う必要があります。ラッパークラスでラップすると冗長になります。ラッパー クラスが必要な唯一の理由は、テストを作成するためです。Moles により、ラッパー クラスなしでテストを記述できます :)

于 2011-04-21T09:01:28.277 に答える