😺

connecttest: ConnectRPC 向けの軽量テスト DSL

に公開

本記事は ChatGPT によって書かれた

connecttest: ConnectRPC 向けの軽量テスト DSL

ConnectRPC でハンドラのテストを書くたびに、毎回 httptest.Server やクライアントの初期化、レスポンスコードやヘッダーの検証、connect.Error のデコードなど、同じようなコードを書いていることに気づきました。

「もっとシンプルに、ハンドラを直接実行して挙動を確認できたらいいのに」──そう思って作ったのが connecttest です。

connecttest は、httptest を使って ConnectRPC のハンドラを直接実行し、レスポンスを直感的にアサートできる DSL です。


使う理由

ConnectRPC は非常に良いフレームワークですが、ハンドラテストは往々にして冗長になりがちです。

たとえば、従来の書き方は次のようになります。

req := connect.NewRequest(&authv1.SignInRequest{...})
res, err := client.SignIn(context.Background(), req)

ステータスコードやヘッダー、エラー内容を検証するたびに同じ処理を繰り返す必要があります。

connecttest を使うと、テストはもっとシンプルになります。

var out authv1.SignInResponse
connecttest.
    New(t, either.Right(authv1connect.NewSessionServiceHandler(handler.NewSession()))).
    Procedure(authv1connect.SessionServiceSignInProcedure).
    In(&authv1.SignInRequest{
        Email:    "user@example.com",
        Password: "password123",
    }).
    Do().
    ExpectStatus(http.StatusOK).
    Out(&out)

require.NotZero(t, out.Tokens)

特徴

  • httptest によるローカル実行(ネットワーク不要)

  • connect.Error の JSON レスポンスを自動デコード

  • 直感的なアサーションメソッド:

    • ExpectStatus
    • ExpectHeader
    • Out(Protobuf レスポンスのアンマーシャル)
    • Err*connect.Error を直接返す)
  • connect.ErrorDetail の構造化デコードに対応

  • connect.WithInterceptors(...) にも対応


導入

go get github.com/mickamy/connecttest

エラーの扱い

Err()*connect.Error を直接返します。

if err := ct.Err(); err != nil {
    fmt.Println(err.Code(), err.Message())
}

connect.Error の詳細情報を使えば、ErrorDetail の検証も簡単です。


まとめ

connecttest は、ConnectRPC ハンドラのテストをより軽く、読みやすくするためのツールです。

**「テストの本質は挙動を確認すること」**──その原点に立ち返るための DSL として設計しました。

リポジトリはこちらです:
github.com/mickamy/connect-go-test

Discussion