🐁

Go の ogen でテストを実装する3つのパターン

2024/06/29に公開

はじめに

ogen 関連シリーズ第3弾です。
シリーズ化するとともに ogen がどんどん好きになっています。

第1弾

https://zenn.dev/otakakot/articles/43653194611d42

第2弾

https://zenn.dev/otakakot/articles/8f15c1bc906e4e

今回は ogen でテストを実装する際に使える3つのパターンをご紹介します。

ogen

https://ogen.dev/

OpenAPI からコードを自動生成することができ、以下のような特徴があります。

  • 生成されたコードで refrect や interface{} を使わない
  • 独自のルーティング機構
  • 標準の OpenAPI v3 で完結
  • Optional や Nullable に対応
  • OpenTelemetry に対応

3つのテストパターン

今回紹介する3つのパターンは以下の通りです。

  1. Handler パターン
  2. httptest.NewRecoder() パターン
  3. httptest.NewServer() パターン

メリットデメリットを記載していますが、一般論ではなく筆者体感です。あらかじめご了承ください。

Handler パターン

ogen の interface を満たすために実装したメソッドに対して直接テストを実行する方法です。

https://github.com/otakakot/sample-go-ogen/blob/main/test/e2e/handler_test.go

メリット

デメリット

httptest.NewRecoder() パターン

net/http/httptestNewRecorder を使ってテストを実行する方法です。

https://github.com/otakakot/sample-go-ogen/blob/main/test/e2e/httptest_test.go

メリット

  • ogen によらないリクエスト値を設定できる
  • Convenient errors に対してテストができる

デメリット

  • 正常系と異常系の型が異なるのでテーブル駆動テストが書きづらい(センスが必要)

httptest.NewServer() パターン

net/http/httptestNewServer を使って実際にサーバーを起動しそこに対してテストを実行する方法です。

https://github.com/otakakot/sample-go-ogen/blob/main/test/e2e/server_test.go

メリット

  • ogen のクライアント生成コードを使ってテストが書ける(使い方を提示できる)

デメリット

  • レスポンスの型が異なるのでテーブル駆動テストが書きづらい(センスが必要)
  • クライアントの実装が必要なので少しめんどくさい

おわりに

個人的には httptest.NewRecoder を利用したパターンがお気に入りです。

(ほかにもあるかもしれません。ありましたら教えてください!)

今回実装したコードは以下に置いておきます。

https://github.com/otakakot/sample-go-ogen

Discussion