Java用の偽のファイルシステムフレームワークはありますか?[閉まっている]


83

IO操作(この場合はファイルシステム)を多用するプロジェクトにテストを導入しています。システムは常にファイルを開いたり閉じたり、ファイルが存在するかどうかをチェックしたり、ファイルを削除したりします。

定期的なモックはあまり役に立たないことがすぐに明らかになりました。それは私のテストをセットアップして推論するのを難しくするからです。一方で、偽のファイルシステムを持つことは素晴らしいことであり、セットアップは非常に簡単だと思います。

ルビーの人たちがまたやったようです。私がルビーに求めているのはまさにそれです:http//ozmm.org/posts/fakefs.html

Javaにリモートで似ているものはありますか?


1
これは、静的型システムのない言語で行うのが簡単なアプリケーションレベルのようです。Javaでは、VMにパッチを適用しない場合、File / FileInputStream / FileOutputStreamは常に基盤となるシステムのファイルシステムを参照します。
–PaŭloEbermann 2011

JavaFileManagerFileSystemViewのような実装可能なインターフェースがありますが、ほとんどのプログラムはそれらを使用しません。
–PaŭloEbermann 2011

@ 1番目のコメント:私はそれをよく知っています。私は現在、Fileのすべての使用法を、ファイル名を文字列としてのみ含む独自のファイル名に置き換えました。すべてのIOロジックはIFileSystemインターフェイスに集中していました。私が抱えている問題は、偽のファイルシステムを必要な方法で実装するのがまだ丸一日のようであるということです(ファイル+フォルダー+隠しファイル+名前変更+ファイル名からパスのみを取得するサポート付き) + ...)そしてそれをテストして、それが実際に正しいことを知る。
貪欲なエリジウム2011

1
OPでRubyについて言及されたので、ここで、C#にも同等のSystem.IO.Abstractionsがあり、最近使用し始めて非常に優れていることを付け加えておきます。
julealgon 2014年

回答:


52

Googleには、Java7のFileSystemProviderのオープンソースのメモリ内実装があります。このプロジェクトはjimfsと呼ばれます


Java 6以前を使用している場合は、別の方法があります。以前はApache CommonsVFSを使用して大成功を収めました。別の回答者が言及したカスタムFileSystemProviderがJava7にあるのとよく似ているようです。

いくつか例を挙げると、ファイル、RAM、S / FTP、Jarなどのいくつかのファイルシステム実装がプリロードされています。S3のプラグインも見ました。


6
jimfsに+1します。これにより、1回の変更なしでコードをテストできました。(私はPath偶然に使用しました)
user1071136 2014年

35

以下のようなクラスのためのJava 6およびそれ以前のことは困難であるFileとは、FileInputStreamJavaの空間で異なる「仮想ファイルシステム」に派遣する方法を提供しません。

Java 7では、仮想ファイルシステムがサポートされています。カスタムファイルシステムプロバイダーの開発を参照してください。これでやりたいことができるかどうかはわかりませんが、探し始めるのに良い場所です。


まあ。実際には偽のファイルシステムがないように見えるので、最小限の実装を自分で実装するだけだと思います。FileSystemProviderを使用しても何も勝ちません

実際には、FileSystemProviderを使用して勝ちます。

  • あなたは(オープンソースライセンスの下でリリースされた場合)あなたの立場にある他の人々にとって、そして他の目的のために非常に役立つかもしれない何かを実装します。

  • 他の誰かが現在作業している可能性のあるFileSystemProviderに切り替えることにした場合は、自分で簡単に行うことができます。


興味深いですが、ファイルシステムを自分で実装する必要があるようですが、それほど有用ではありません
;

6
少なくともそれあなたがそれをすることを可能にします。そして、あなた自身が言ったように- 「セットアップは簡単でしょう」
スティーブンC

まあ。実際には偽のファイルシステムがないように見えるので、最小限の実装を自分で実装するだけだと思います。FileSystemProviderを使用しても何も勝ちません。
貪欲なエリジウム2011

@ devouredelysium-私のアップデートを参照してください。
スティーブンC

2
書き込みおよびオープンソース・INGの溶液推奨する+1
WickyNilliams

19

JUnitパッケージorg.junit.rules.TemporaryFolderから使用できます。

TemporaryFolderルールを使用すると、テストメソッドの終了時に(合格か不合格かにかかわらず)削除されることが保証されているファイルとフォルダーを作成できます。

例:

final TemporaryFolder testFolder = new TemporaryFolder();
testFolder.create();
final Path filePath = testFolder.newFile("input.txt").toPath();
final Path dirPath = testFolder.newFolder("subfolder").toPath();

または、.toPath()パーツを終了します。

final File filePath = testFolder.newFile("input.txt");

TemporaryFolderはメモリ内にありません。
progonkpa

8

FileAPIを変更して、のOutputStream代わりにを使用することで「データを書き込む場所」の意図を使用しての使用を抽象化し、本番コードでFileAPI aFileOutputStreamを渡しByteArrayOutputStreamますが、テストからは渡します。AByteArrayOutputStreamはメモリ内ストリームであるため、非常に高速であり、メソッドを使用してコンテンツを簡単に検査できます。テストに最適です。データByteArrayInputStream読みたい場合は、対応するものもあります。

ファイルシステムは一般的にかなり高速です-テストで大量のファイルI / Oを実行していない限り、私は気にしません。

JavaFileオブジェクトを作成しても、ディスク上にファイル作成されないことに注意してください。つまり、次のコードはディスクに変更を加えません。

File f = new File("somepath"); // doesn't create a file on disk

new File( "something")はディスク上にファイルを作成しませんが、そのメソッドのほとんどすべてを実行しようとすると、ファイルシステムが使用されます。。..私は何を意味するかを確認するために、新たなファイル(「XYZ」)getAbsolutePath()を試してみてください
とりこエリュシオン

1
私の主な関心事はスピードだと人々は思っていると思います。そうではない。
貪欲なエリジウム2011

1
ファイルシステムなどのリソースを抽象化することは常に良い習慣だと思います(DBにデータアクセス層を書き込むのと同じ方法です)。これは通常、最下位レベルのクラスの周りにインターフェイスと薄いラッパーを作成することによって実現されます。プログラムの最高レベルで依存性注入を使用すると、アプリケーションを介してモックファイルシステムを非常に簡単に伝播できます(モックフレームワークを使用する必要はなく、インターフェイスの「ダミー」実装であることに注意してください)。
WickyNilliams 2011

@devouredelysiumnew File("xyz").getAbsolutePath()は、ファイル存在する場合にファイル持つパスを返す以外は、まったく何もしません。ファイルシステムは変更されません。ファイルが存在しない場合でも、パスの文字列を返し、ファイルを作成しません。「何が起こるか見る」とはどういう意味ですか?
ボヘミアン

1
File私のOpenJDKの7の最終ではありません
Dzmitry Lazerka

6

GoogleによるJimfsは、メモリ内のNIOファイルシステムであり、テストに最適です。


4

簡単な方法は、完全にRAMに基づいたファイルシステムを提供するシステムの方法を使用することです。Linuxではtempfs、WindowsではRAMディスクです。


(速度以外の)真のファイルシステムを使用するよりも、それがどのように優れているかはわかりません。
貪欲なエリジウム2011

ええ、速度(およびディスクの摩耗)が主な理由です。申し訳ありませんが、私はあなたの目標を誤解したかもしれません。
–PaŭloEbermann 2011

1
私の目標は、テストを簡単にすることです。現在、パフォーマンスには関心がありません。
貪欲なエリジウム2011

4

MockFTPServerには、いくつかの偽のファイルシステム実装があるようです(Unix / Windows)

これらの偽のファイルシステム実装は、FTPの概念とはまったく別に使用できるようです。私は今、あなたが概説したのとまったく同じ目的でこれを試しています。


UnixFakeFileSystemを使用しています。私のFileSystem抽象化の偽の実装として非常にうまく機能しています。
Deano 2011

2

特定のフレームワークについてはよくわかりませんが、OOPに関する一般的なアプローチは、ファイルアクセスコード(インターフェイスが豊富!)の上に抽象化されたレイヤーを記述し、一般的な操作を簡単に使用できるようにすることです。次に、現在テストしているコードの1つ下のレイヤーをモックし、それは本質的に偽のファイルシステムです(または、少なくともテストしているコードは他の方法ではわかりません)。

依存性注入フレームワークを使用してこれを処理することを検討すると、インターフェイスの偽の実装のためにコンポーネントを切り替える機能が容易になります。制御の反転のパターンに従う場合、テストしているクラスのコンストラクターに依存関係を渡すと、テストも簡単になります。

public interface IFileSystem {
   IFileHandle Load(string path);
   //etc
}

public class ClassBeingTested {
   public ClassBeingTested(IFileSystem fileSystem) {
      //assign to private field
   }

   public void DoSomethingWithFileSystem() {
       //utilise interface to file system here
       //which you could easily mock for testing purposes
       //by passing a fake implementation to the constructor
   }
}

私のJavaが正しいことを願っています、私は長い間Javaを書いていませんが、うまくいけばドリフトを得るでしょう。うまくいけば、私はここで問題を過小評価しておらず、過度に単純化しています!

もちろん、これはすべて、真の単体テスト、つまり、システム全体ではなく、可能な限り最小のコード単位をテストすることを意味していることを前提としています。統合テストには、別のアプローチが必要です。


1
偽のファイルシステムには独自のロジックが必要です。他のファイルシステムと同じようにファイルシステムですが、それはメモリにのみ存在します。そのようなファイルシステムを自分でプログラムする必要は避けたいと思います。
貪欲なエリジウム2011

どのタイプのファイルシステム操作を模倣しようとしていますか?ファイルのロック?読み書き?または、ファイルを開く、ディレクトリが存在することを確認する、ファイルを作成するなどの簡単なことですか?
WickyNilliams 2011

ファイルがファイルであるかディレクトリであるかをチェックし、存在する場合は、ファイルを作成し、ファイルを削除する、ほとんどの単純な操作。これは、もちろん、等「の絶対パスからの相対パスを取得する」とは、「このファイル名からパスを取得」として複数のフォルダおよび動作をサポートしながら
とりこエリュシオン

私が述べたように、物理ファイルシステムの周りに抽象化を作成し、アプリ全体で常にそれを使用します(常にインターフェイスに対してコーディングします)。次に、依存性注入を使用して、テスト対象を伝播します。私はそれが単調な仕事であることを知っていますが、プログラマーとして、
関心の分離を明確にし

あなたは本当にここで求められていることを理解していません。私は偽のファイルシステムを探していた場合、私はので、それがなければなりません、すでに(OPのコメントで述べたように)私のアプリでファイルシステム全体の抽象化を行いました。私はちょうど..私のテストで使用するファイルシステムの偽の実装を必要とする
とりこエリュシオン

2

ArquillianプロジェクトのShrinkWrapは、メモリファイルシステムにNIO準拠を含むように見えます

次の手順を実行して、単純なメモリ内ファイルシステムを作成できます。

FileSystem fs = ShrinkWrapFileSystems.newFileSystem(ShrinkWrap.create(GenericArchive.class))

file://プロトコルをサポートしていますか、ドキュメントが見つかりません...
Marco Vasapollo 2015年


0

「FakejavaFileSystem」をグーグルで検索していて、この質問を見つけました。残念ながら、これが私が見つけたすべてです。だから私はこの偽のファイルシステムを自分で書いた:https//github.com/dernasherbrezon/mockfs

ファイルの読み取り/書き込み中のIOExceptionをシミュレートするために使用しています。IOExceptionは、たとえば「ディスク容量がない」ために発生する可能性があります。これは、他の方法でシミュレートすることはほぼ不可能です。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.