唐紅に水くくるとは

通年チョコミントを食べたい

ServletOutputStreamの取得

とあるテストケースで、
ServletOutputStream.writeを使った結果をassertしたくなりました。

ググってもググってもByteArrayOutputStream使えばいいよ!という答えしか出てこなくて
途方に暮れた。。。

が、assertの方法をちょっと変えることで回避。
ResponseWrapper#getResponseBody の結果のbyte[]でassertすることにした。
具体的にはこんな感じで

        // 外側のクラスをインスタンス化
        final SampleResponseWrapper target = new SampleResponseWrapper(res);
        // mockのresponseを使って、privateメソッドを呼び、outputStreamを詰め込む。
        target.getOutputStream();

        ServletOutputStream csrw = (ServletOutputStream) field.get(target);
        csrw.write(129);

        // 結果のbyte配列をint型に変える
        int intValue = 0;
        for (byte b : target.getResponseBody()) {
            intValue = b;
            if (intValue < 0) {
                intValue += 256;
            }
        }

        assertEquals(129, intValue);


テスト対象のクラスは、ざっくりこんな感じ

public class SampleResponseWrapper extends HttpServletResponseWrapper {

    /** 出力バッファ */
    private InnerClassOutputStream wrappedOut;

    /** 内部クラス */
    private static class InnerClassOutputStream extends ServletOutputStream {

        /** 内部クラスの出力バッファ */
        private ByteArrayOutputStream buffer;

        @Override
        public void write(int b) throws IOException {
            buffer.write(b);
        }
    }

}

SampleResponseWrapper は、HttpServletResponseWrapperを継承したクラス。
その中のフィールドに「wrappedOut」がいて、
その型はSampleResponseWrapper の内部クラス(private static)。

結局本質的なテストができてない気はムンムンしつつ、
思ったことは、
何でもかんでもprivateにしないで・・・ということ(自分が作ったクラスじゃないので)

いや、必要ならprivateでももちろん構わないけど、
単体テストカバレッジを見逃すとか、そういう配慮的な何かがほしかった。

テスト設計って、大事だなーって。
カバレッジ100%っていうのは管理上確認するのは簡単だけど、
本当にそのテストが品質を担保してるのか?っていったら微妙だと思う。
(むしろ、カバレッジを上げるのに時間を使ってしまって、
 単体テストケースを考えたりレビューしたりする時間が減るのではないかと。)

テストケース(しかも単体)なんて、もっと機械的にできてもいいのになぁ??と
思ってしまう自分でした。