回答:
外部リソースを使用してTDDで常に行うように、ファイルシステム操作への1つ以上のインターフェイスを作成し、「モックアウト」します。ファイルシステム操作自体ではなく、「テーブルジェネレータ」とメタデータ変更コードをテストする必要があります(ほとんどの場合、ファイルシステムへのアクセスに既製のライブラリ実装を使用しています)。
「テスト」ファイルシステムの問題は何ですか?
操作をテストするのに十分なコンテンツを含むテンプレートフォルダー/ディレクトリ構造を作成します。
ユニットテストのセットアップ中に、この初期構造をコピーします(テンプレートを圧縮してテスト領域に解凍することをお勧めします)。テストを実行します。分解中にすべてを削除します。
モックの問題は、最初にファイルシステム、プロジェクトに属するOSおよびデータベースが外部リソースとして実際に適格ではないこと、および2番目に低レベルのシステムコールをモックすると時間がかかり、エラーが発生しやすいことです。
これは、実際のファイルシステムにはあらゆる種類の奇妙な動作があるため、統合テストに必ず必要なものです(削除者を含むプロセスが開いている場合、Windowsがファイルの削除を許可しない方法など)。
そのため、TDDのアプローチでは、最初に統合テストを作成します(厳密には、TDDには「単体テスト」と「統合テスト」という概念はありません。これらは単なるテストです)。それで十分でしょう。そのジョブは、ストップを行って、家に行きます。
そうでない場合、ファイルを配置することで適切にテストするのは容易ではない内部の複雑さがあります。その場合、単純にその複雑さを取り除き、クラスに入れ、そのクラスの単体テストを作成します。その共通クラスは、データベース、xmlファイルなどのケースでも使用できることがわかるでしょう。
どのような場合でも、テスト対象のユニットが間違っているかどうかに合格するテストを作成するために、作成中のコードの基本的なコアを取り出して「モック」を作成することはありません。
'unit test' and 'integration test'; they are just tests.
現実的には、これは私のケースにとって最良のソリューションになると思います- エッジケースに使用しているファイルシステムライブラリとアプリケーションの応答方法をテストする必要がありますそれら。別のファイルシステムライブラリに切り替えた場合、新しいライブラリを使用するために多数のモック/テストコードを書き直す必要はありませんが、テストフォルダー構造と統合テストがあれば、より簡単になります。
私はあなたの質問を「ファイルシステムの操作に依存するクラスをテストする良い/受け入れられた方法」として理解しています。OSのファイルシステムをテストしたいとは思いません。
@Doc Brownの回答が可能な限り小さいと示唆したように、「ファイルシステム操作へのインターフェースと「モックアウト」」の努力を続けるために、Java バイナリストリームまたはテキストリーダー(またはc#で同等のもの)を使用することをお勧めします使用しているプログラミング言語)ファイルをファイル名で直接使用する代わりに、 tdd開発クラスで直接使用します。
例:
Javaを使用して、クラスCsvReaderを実装しました
public class CsvReader {
private Reader reader;
public CsvReader(Reader reader) {
this.reader = reader;
}
}
テストのために、私はこのようなメモリデータを使用しました
String contentOfCsv = "TestColumn1;TestColumn2\n"+
"value1;value2\n";
CsvReader sut = new CsvReader(java.io.StringReader(contentOfCsv));
またはリソースにテストデータを埋め込む
CsvReader sut = new CsvReader(getClass().getResourceAsStream("/data.csv"));
本番では、ファイルシステムを使用します
CsvReader sut = new CsvReader(new BufferedReader( new FileReader( "/import/Prices.csv" ) ));
このように、私のCsvReaderはファイルシステムに依存せず、ファイルシステムの実装がある抽象化「リーダー」に依存します。