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%っていうのは管理上確認するのは簡単だけど、
本当にそのテストが品質を担保してるのか?っていったら微妙だと思う。
(むしろ、カバレッジを上げるのに時間を使ってしまって、
単体テストケースを考えたりレビューしたりする時間が減るのではないかと。)
テストケース(しかも単体)なんて、もっと機械的にできてもいいのになぁ??と
思ってしまう自分でした。