2012-02-17 10 views
9

出力ストリームをjavaで以下のようにテストしています。ファイルを作成せずにoutputstream.write(<String>)をテストする

Writer outputStream = getOutputStream(fileName); 
    if(outputStream != null) { 
     try { 
      outputStream.write(inputText); 
     } 
     finally { 
      outputStream.close(); 
     } 
    } 
    else { 
     throw new IOException("Output stream is null"); 
    } 

私はあなたがディスク上の物理ファイルが作成されOutputStreamWriter(new FileOutputStream(filename))を作成するときに問題がある

public void testFileWrite() throws IOException { 
    when(testObj.getOutputStream(outputFileNameValidValue)).thenReturn(outputStreamMock); 
    doNothing().when(outputStreamMock).write(Matchers.anyString()); 
    doNothing().when(bufferedReaderMock).close(); 

    testObj.write(outputFileNameValidValue, reveredFileInput); 

    verify(outputStreamMock).write(Matchers.anyString()); 
    verify(outputStreamMock).close(); 
} 

以下のようにmockitoテストを記述しています。

実際にファイルをディスクに書き込まずにOutputstream.writeをテストできますか?

おかげ アナンドは

+1

明確にしてください - どこで 'OutputStreamWriter'を作成しない - 私はあなたのコードでそれを見ることはありませんが。私はそれが 'getOutputStream'の中にあると思います - あなたがこのメソッドを外したことを除いて。人々があなたを助けてくれるようにするには、すべてのコードを投稿する必要があります。また、 'OutputStream'を取得しないので、' getOutputStream'はおそらく別のもの(おそらく 'makeWriter')と呼ばれるべきです。 –

+0

getOutputStreamメソッドです。理由は、私はmockitoはmthodを実行し、モックを返すことはありません希望とメソッドに移動した理由。私は間違っています。 – Anand

+0

グーグルといくつかのドキュメントを読んだところ、PowerMockはこれを簡単に実行できることを発見しました。 expectNewまたはsuppressConstructorとWhitebox.setInsternalStateを使用します。 PowerMockでこのようなことをテストするのは簡単です。あなたのコメントと答えに感謝します..について、Anand Barhate – Anand

答えて

9

あなたはメモリにデータを書き込むByteArrayOutputStreamを使用することができます。これはByteArrayInputStreamで読み取ることができます。

また、誤ったバイトを書き込もうとするとすぐに失敗する、期待されるOutputStreamを書き込む方法もあります。これは、テストがどこで失敗するのかを正確に確認するのに役立ちます。

+0

Ok .. ByteArrayOutputStreamを使って書き込みを行い、ついにはwriteToを使ってファイルに書き込む必要がありますか?しかし、遅かれ早かれ、私は同じ問題に直面するでしょう、それはありませんか? XXStreamWriterはファイルを書き込む必要があり、それは私がMockitoの使用を避けたいビットです。 – Anand

+1

私は分かりません。なぜあなたはファイルに書き込む必要がありますか? –

0

getOutputStreamをモックアップする必要があります。モックされた出力ストリームオブジェクトを返す必要があります。 new FileOutputStreamの呼び出しは実際にディスク上にファイルを作成します。

理論上、ファイルシステム自体をモックアップすることはできますが、はるかに複雑です。

BTW if(outputStream != null)は冗長です。ストリームをnullにすることはできません。作成できない場合、メソッドは例外をスローする必要があります。それはCではなく、Javaです。 :)

+0

実際にこれは私が行ったことです\t \t(testObj.getOutputStream(outputFileNameValidValue))。then return(outputStreamMock); でも、私が電話すると、\t \t testObj.write(outputFileNameValidValue、reveredFileInput); それでもファイルに空文字列が書き込まれます。だから、実際にディスクにファイルを作成するのを避けるために、ファイルシステムを模擬しなければならないようです。 – Anand

+0

if(outputStream!= null)これに同意します。私はちょうど防衛プログラミングに使用されています:) – Anand

0

getOutputStream(String)を返信すると、java.io.StringWriterが返され、予想される内容が書き込まれたことを表明できます。

public void testFileWrite() throws IOException { 
    StringWriter writer = new StringWriter(); 
    when(testObj.getOutputStream(outputFileNameValidValue)).thenReturn(writer); 

    testObj.write(outputFileNameValidValue, reveredFileInput); 

    assertEquals(reveredFileInput, writer.toString()); 

    verify(writer).close(); 
} 
1

すでに提案されているように、テスト対象のクラスにmocked OutputStreamを挿入できる必要があります。テスト対象のクラスは、指定されたファイルに書き込むOutputStreamを必要とするため、テスト対象のクラスにモック可能なOutputStreamFactoryを注入する必要があります。

私は完全に自己完結型であるあなたのために、このコードを持っている:

import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mock; 
import org.mockito.runners.MockitoJUnitRunner; 

import java.io.IOException; 
import java.io.OutputStream; 

import static org.mockito.Mockito.verify; 
import static org.mockito.Mockito.when; 

@RunWith(MockitoJUnitRunner.class) 
public class Test9328173 { 

    private ClassUnderTest testObj; 

    @Mock 
    private OutputStreamFactory factory; 

    @Mock 
    private OutputStream stream; 

    @Before 
    public void setUp() throws Exception { 
     testObj = new ClassUnderTest(); 
     testObj.factory = factory; 
    } 

    @Test 
    public void testFileWrite() throws Exception { 
     when(factory.create("filename")).thenReturn(stream); 

     testObj.write("filename", new byte[]{1, 2, 3}); 

     verify(stream).write(new byte[]{1, 2, 3}); 
     verify(stream).close(); 
    } 

    private class ClassUnderTest { 

     private OutputStreamFactory factory; 

     public void write(String filename, byte[] content) throws IOException { 
      OutputStream stream = factory.create(filename); 
      try { 
       stream.write(content); 
      } finally { 
       stream.close(); 
      } 
     } 
    } 

    private interface OutputStreamFactory { 

     OutputStream create(String filename); 
    } 
} 
+0

確かに。 setter/constructorの引数/ @Injectアノテーションは、ファクトリより少し簡単かもしれませんが、ストリームが正しい指示を受け取っているかどうかを確認する方法です。 – avandeursen

関連する問題