Goでpstestライブラリを使ってCloud PubSubのテストを楽に書く
Google Cloud Platform(GCP)を使っており、非同期でなにかを処理したいときCloud PubSubを用いる人は多いと思います。GolangでPubSubを使ったコードを書くとき、テストしやすいようにinterfaceを切るのは結構だるい。
結局interfaceで隠蔽した部分の単体テストが書けなくて、そこがバグのもとになったりする。
そんなときGoogle公式が提供してくれているpstestライブラリを使うと、
PubSubインフラ部分をmockしてくれて単体テストがさらっとかけてストレスフリーです。
実際のサンプルコードを見てみましょう。
package example_test import ( "context" "fmt" "testing" "cloud.google.com/go/pubsub" "cloud.google.com/go/pubsub/pstest" "google.golang.org/api/option" "google.golang.org/grpc" ) func TestPubSub(t *testing.T) { srv := pstest.NewServer() conn, _ := grpc.Dial(srv.Addr, grpc.WithInsecure()) cctx, cancel := context.WithCancel(context.Background()) client, _ := pubsub.NewClient(cctx, "projectID", option.WithGRPCConn(conn), ) topic, _ := client.CreateTopic(cctx, "topicID") subscription, _ := client.CreateSubscription(cctx, "subscriptionID", pubsub.SubscriptionConfig{Topic: topic}, ) topic.Publish(cctx, &pubsub.Message{Data: []byte("example message data")}) _ = subscription.Receive(cctx, func(ctx context.Context, message *pubsub.Message) { fmt.Printf("received a message:%v\n", string(message.Data)) message.Ack() cancel() }, ) }
たったこれだけのコードですが、TopicとSubscriptionを作り、
Topicにメッセージを送信してSubscriberに受け取らせ画面に表示するところまでやってくれます。
ポイントはpstestライブラリが作ったgRPC connectionをpubsub.NewClient()にinjectしていること。
本番環境向けのコードでは、これをinjectしないようにif文書き足すだけでも動きそうです。
サンプルコードを実行してみるとこんな感じ。
=== RUN TestPubSub
received a message:example message data
--- PASS: TestPubSub (0.97s)
PASS
インメモリなPubSubとして使えるといっても過言ではないですね。
みなさんもぜひ使ってみてください!