gin の SSE ストリーミングハンドラーは httptest 標準レコーダーではテストできない
Go
Gin
テスト
gin の c.Stream() / SSE を使うハンドラーを httptest.NewRecorder() でテストすると、interface conversion: *httptest.ResponseRecorder is not http.CloseNotifier で panic する。gin の Stream 実装がクライアント切断検知に http.CloseNotifier を要求するが、標準のレコーダーは実装していないため。
対処: レコーダーをラップして CloseNotify を生やすだけでよい。
これを router.ServeHTTP(&closeNotifyRecorder{httptest.NewRecorder()}, req) のように渡す。チャネルを閉じなければ「切断されないクライアント」として振る舞う。切断時の挙動をテストしたい場合は、閉じるチャネルを返す版を作る。
併せてハマりやすい点:
- Content-Type の検証は完全一致にしない。
c.SSEvent経由だとtext/event-stream;charset=utf-8のように charset が付くため、Containsで判定する。 - ストリーム源がチャネルの場合、バッファ付きチャネルに値を入れて close してから渡せば、ハンドラーは同期的に全イベントを書き切って返るので、goroutine 同期なしで本文を検証できる。
適用条件: gin で SSE / chunked ストリーミングを返すエンドポイントのハンドラー単体テスト全般。