Iruca Log

Iruca Log

東京に住むWeb系エンジニアによる技術&雑記ブログ

SNSでフォローする!

Goでpstestライブラリを使ってCloud PubSubのテストを楽に書く

message

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として使えるといっても過言ではないですね。
みなさんもぜひ使ってみてください!