14

私はRunnable次の線に沿っています:

    public void run() {
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file);
            //more stuff here
        } 
        catch (Exception e) {
            //simplified for reading
        }
        finally {
            if(inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {}
            }
        }
    }

inputStream.close()呼び出されたテストを行うにはどうすればよいですか?現在、MockitoとJUnitを使用しています。inを挿入するのinputStreamはアイデアですが、が呼び出されるまでリソースを使用したくないrun?()ので、ローカル変数になります。では、closeが呼び出されたかどうかをテストできるようにコードを再設計するにはどうすればよいですか?

4

6 に答える 6

18

タスクを正しく理解していれば、このようになる可能性があります

static boolean isClosed;

public void run() {
    InputStream inputStream = null;
    try {
        inputStream = new FileInputStream(file) {
            @Override
            public void close() throws IOException {
                isClosed = true;
                super.close();
            }
        };
        // more stuff here
于 2012-12-10T11:47:36.737 に答える
7

このメソッドのスコープ外に InputStream を公開する理由がないため、テストに問題があります。

InputStreamしかし、閉鎖されていることを直接気にしないと思います。あなたはそれをテストしたいと思っています。しかし、あなたが実際に気にかけているのは、ストリームが開いたままになることによる悪影響だと思います。効果は何ですか?

ストリームを閉じないようにこのメソッドを変更してから、何度も実行してみてください。メモリ リークが発生したり、ファイル ハンドルが不足したり、その他のおかしなことをしたりしませんか? もしそうなら、あなたは合理的なテストをしています。

または、閉じられているかどうかを示す装飾された InputStream を公開してください。パッケージを保護します。それは「不純」ですが、実用的なアプローチです。

于 2012-12-10T11:48:12.653 に答える
7

close() メソッドが呼び出されたかどうかを確認するには、Mockito.spy() を使用して、呼び出しを記憶できるプロキシ オブジェクトを作成します。Spy は、基礎となる InputStream へのすべての呼び出しを委譲し、何が起こったかを記憶するだけです。

InputStream inputStreamSpy = Mockito.spy(inputStream);
// a code that is expected to close your stream goes here ...
Mockito.verify(inputStreamSpy).close();

実際、これは InputStream のインスタンスを注入する際の問題を解決しません。ストリームを開くことができるある種のファクトリが必要なようで、ユニットテストでそのファクトリをモックできます。このファクトリを FileSystem と呼びましょう:

public class FileSystem {
    public FileInputStream newFileInputStream(File file) {
        return new FileInputStream(file);
    }
}

これで、FileSystem のインスタンスを注入できるようになり、run メソッドが実行される前にリソースを使用しなくなります。

public void run() {
    InputStream inputStream = null;
    try {
        inputStream = fileSystem.newFileInputStream(file);
        //more stuff here
    } 
    catch (Exception e) {
        //simplified for reading
    }
    finally {
        if(inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {}
        }
    }
}

@Test
public void runShouldCloseInputStream() {
    InputStream inputStream = ...
    InputStream inputStreamSpy = Mockito.spy(inputStream);
    FileSystem fileSystemMock = Mockito.mock(FileSystem.class);
    when(mockFileSystem.newFileInputStream(Mockito.any(File.class)))
        .thenReturn(inputStreamSpy);

    MyRunnable instance = new MyRunnable(mockFileSystem);
    instance.run();

    verify(inputStreamSpy).close();
}

Spy は聞くだけでなく、通常のモックと同じように、Mockito.when() を使用して動作を変更するように教えることができます。

于 2017-03-08T03:42:43.200 に答える
1

URL ストリームをテストするための Kotlin 実装は終了しました

//close the connection
streamURL.close()

//stream should not be available if it is closed
try { streamURL.available() }

//java.net.URL provides simple "closed" message on IO URL
catch (ex: IOException) { Assert.assertEquals("closed", ex.message) }
于 2019-02-15T11:16:40.387 に答える
0

あなたはこのようにすることができます...

    try
    {
         inputStream.readLine();        
    }
    catch (IOException e)
    {
        Assert.assertEquals(e.getLocalizedMessage(), "Stream closed");
    }
于 2015-06-12T17:48:14.607 に答える
0

テストに次のように書くことができます:

try {
    run();
} catch (IOException e) {
    Assert.fail();
}

メソッドが strem を閉じて例外が発生すると、テストは失敗します。

于 2012-12-10T13:33:24.423 に答える