はじめに
こんにちわ、すえけん(@sueken5)です。この記事ではspannerのエミュレータであるhandy-spannerを使ってspannerのコードをテストするやり方を紹介します。
handy-spanner
handy-spannerはgcpugで管理されているプロジェクトで非公式ではありますがspannerをエミュレートするツールです(リンク)。
できることとできないことがREADME.mdに書かれているのでチェックしておきましょう。
built in server
handy-spannerはgolangで書かれていてテストプロセスの中でエミュレータを起動して使うことができます。なのでDockerなどを用意する必要がないためとても簡単にテストできます。
//https://github.com/gcpug/handy-spanner/blob/master/fake/example_test.goより抜粋
func ExampleSpannerClient() {
ctx := context.Background()
dbName := "projects/fake/instances/fake/databases/fake"
// Run fake server
srv, conn, err := fake.Run()
if err != nil {
log.Fatal(err)
}
defer srv.Stop()
defer conn.Close()
// Prepare spanner client
client, err := spanner.NewClient(ctx, dbName, option.WithGRPCConn(conn))
if err != nil {
log.Fatalf("failed to connect fake spanner server: %v", err)
}
// Use the client
_, _ = client.Apply(ctx, []*spanner.Mutation{
spanner.Insert("Test",
[]string{"ColA", "ColB"},
[]interface{}{"foo", 100},
),
})
// output:
}
実際のテストコード
//init_test.go
package spanner_test
import (
"fmt"
"log"
"os"
"testing"
"github.com/gcpug/handy-spanner/fake"
"google.golang.org/grpc"
)
var (
testServer *fake.Server
testConnection *grpc.ClientConn
)
func TestMain(m *testing.M) {
fmt.Println("test main")
// Run fake server
server, conn, err := fake.Run()
if err != nil {
log.Fatal(err)
}
defer server.Stop()
defer conn.Close()
testServer = server
testConnection = conn
ret := m.Run()
os.Exit(ret)
}
TestMain
でhandy-spannerサーバーを起動しておきます。
func TestGet_OK(t *testing.T) {
databaseID := "get-ok"
dbName := fmt.Sprintf(dbFormat, projectID, instanceID, databaseID)
ctx := context.Background()
testCase := struct {
input []byte
key string
expect []byte
}{
input: []byte("OK"),
key: "test",
expect: []byte("OK"),
}
if err := createDatabase(context.Background(), dbName); err != nil {
panic(err)
}
//fakeサーバー起動時に渡されたコネクションを使ってクライアント生成
client, err := spanner.NewClient(ctx, dbName, option.WithGRPCConn(testConnection))
require.Nil(t, err)
s := &spanner.Store{
PKey: testCase.key,
Value: testCase.input,
}
mut := s.Insert(ctx)
_, err = client.Apply(ctx, []*libspanner.Mutation{mut})
require.Nil(t, err)
actual, err := Get(ctx, testCase.key)
require.Nil(t, err)
assert.Equal(t, testCase.expect, actual)
}
TestMain
でサーバーを起動した時に生成されたコネクションを使ってspannerのクライアントを生成します。あとはいつも通りテストするだけです。
まとめ
簡単にテストできたのでとてもよかったです。