2017-08-23 248 views
1

ファイル/ストリーム処理を行うクラスをテストしようとしています。例えば、方法readFileは、内部のファイルのすべての行と列のArrayListを返すためにBufferedReaderを使用します。MockitoとBufferedReaderでの練習

public ArrayList<String> readFile(String fileName) 
{ 
    ArrayList<String> result = new ArrayList<String>(); 
    FileReader fr = null; 
    BufferedReader br = null; 
    try { 

     fr = new FileReader(STORAGE_DIRECTORY+fileName); 
     br = new BufferedReader(fr); 
     String sCurrentLine; 

     while ((sCurrentLine = br.readLine()) != null) { 
      result.add(sCurrentLine); 
     } 
    } 
     catch (FileNotFoundException e) { 


      return new ArrayList<String>(); 
     } catch (IOException e) { 

      return new ArrayList<String>(); 
     } 

     br.close(); 
     fr.close(); 


     return result; 
    } 

しかし、私はbufferedReader方法「のreadLine()を」モックするために、Mockitoを使用する場合、FileNotFoundExceptionですFileReaderコンストラクタのためにスローされます。 temporaryFileまたはMock FileReaderコンストラクタを使用する必要がありますか?

@Test 
public void readFileTest5() throws Exception { 
    BufferedReader bufferedReader = Mockito.mock(BufferedReader.class); 
    FileReader fileReader = Mockito.mock(FileReader.class); 
    when(BufferedReader.readLine()).thenReturn("abc"); 
    assertEquals("",new ArrayList<String>(), FileUtil.readFile("abc")); 
} 

は、あなたがあなたのBufferedReaderインスタンスへの入力を模擬する方法がありませんことを意味しFileReaderを模擬する機会がないので、

+0

私の悪い、私はクラスのトップを書く必要があります。 BufferedReaderは、アノテーション(スプリングスタイル)が挿入されたクラスのインスタンスです。 '@MockBean \t private BufferedReader bufferedReader; \t \t @MockBean \t private java.io.FileReader fileReader; \t \t @MockBean \tプライベートファイルファイル。 \t @InjectMocks private com.example.system。FileUtil FileUtil; ' – Nicogo

+1

別のメソッドにバッファ構造を抽出して、そのメソッドをモックして、" readLine "が返す擬似BufferedReaderを返す必要があります。あるいは、おそらく単純なことを模倣しようとしないでください。あなたはリソースリークにはるかに明らかな問題があります。 –

+0

ありがとう、あなたは 'ressource leaks'をどういう意味ですか? – Nicogo

答えて

1

FileUtilはnameで参照されるファイルを読み込むため、ファイルシステムにファイルを作成する必要があります。

ArrayList<String> result = new ArrayList<String>(); 
// combine directory and file name like this 
File f = new File(STORAGE_DIRECTORY, fileName); 
// use try-with-resource here, like this: 
try (BufferedReader br = new BufferedReader(new FileReader(f))) { 

    String sCurrentLine; 

    while ((sCurrentLine = br.readLine()) != null) { 
     result.add(sCurrentLine); 
    } 
    } catch (FileNotFoundException e) { 
     // no need to create a new list 
     return Collections.emptyList() 
    } catch (IOException e) { 
     return Collections.emptyList() 
    } 

    // you don't need to close the reader if you use try-with-resource 

    return result; 
} 

あなたはもちろん、単にファイル#のreadAllLinesを使用することができます。これは、簡単に実装コード上のいくつかの単語が

File tempFile = File.createTempFile("temp", ".tmp"); 
tempFile.deleteOnExit(true); 

によって行われます。

try { 
    return Files.readAllLines(Paths.get(STORAGE_DIRECTORY, fileName), StandardCharsets.UTF-8); 
} catch (IOException e) { 
    return Collections.emptyList(); 
} 
3

readFileBufferedReaderラップFileReaderFileReaderはその方法内を作成しているありがとう。

この手法では、テストが難しくなります。

私はあなたのアプローチを変更することをお勧めします。たとえば:

public ArrayList<String> readFile(BufferedReader reader) { 
    // ... 
} 

次に、あなたのテストは次のようになります。すべてで

@Test 
public void readFileTest() throws Exception { 
    BufferedReader bufferedReader = Mockito.mock(BufferedReader.class); 
    Mockito.when(bufferedReader.readLine()).thenReturn("a", "b", "c", null); 
    List<String> expected = Arrays.asList("a", "b", "c"); 
    Assert.assertEquals("", expected, readFile(bufferedReader)); 
} 

またはMockitoなし:

@Test 
public void readFileTest() throws Exception { 
    BufferedReader bufferedReader = new BufferedReader(new StringReader("a\nb\nc")); 
    List<String> expected = Arrays.asList("a", "b", "c"); 
    Assert.assertEquals("", expected, readFile(bufferedReader)); 
} 

別のアプローチは、実際のファイルを作成することとIEがない、それを読んでいました何かを嘲笑する必要がある。 JUnitのTemporary Folder Ruleを使用して、テスト後のクリーンアップに役立てることができます。

readFile()は、BufferedReaderおよびFileReaderを安全に閉じることはできません。

+0

ありがとう、私はあなたの答えを今日の午後見た。私は私の場合、1つのステップ(私は構造上の問題があるかもしれない)から問題を移動すると思う。しかし、私は今、readFile()を使う別のクラスのメソッドを持っています。この呼び出しは次のとおりです: 'lines = fileUtil.readFile(新しいFileReader(新しいファイル(STORAGE_DIRECTORY、FilenameUtils.getName(context)))))); ' このメソッド呼び出しの回りに、Listを返すプロセスをいくつか作成します。しかし、私がこのメソッドをテストしたいとき、たとえ私がメソッドをモックしてもコンストラクタのFileは見つからない。 どのような方法が最適ですか?一時ファイルを作成しますか? – Nicogo

+1

最後の投稿を正しく追跡しているかどうかは分かりませんが、ここではMockitoを使って遊ぶのを避ける最も簡単な方法は、(a)あらかじめ設定された 'BufferedReader'を' fileUtil.readFile() 'に渡すことです実際のファイルを作成し、それを使用してテストケースで破棄します(JUnitのTemporary FOlder RUleへのリンクを使用すると、作成したファイルを見直すことができます)その後、セマンティクスを破棄する)。 – glytching