0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

BigQuery emulatorを使ったgolangでの単体テストの書き方

Posted at

概要

docker run --name bigquery-emulator -d -p 9050:9050 -p 9060:9060 ghcr.io/goccy/bigquery-emulator:latest --project=test-proj

対象読者

BigQueryの単体テストやローカルで結合テストを気軽に行ないたい方

はじめに

BigQueryみたいなGCPの機能を使った単体テストやローカルで結合テストするのって面倒ですよね。多人数の開発でGCP上のBigQueryを使おうとすると、他の人も使ってることがあるので、データベースの状態の管理が難しいですからね。

GCP上に自分専用のBigQueryを作れればいいのですが、その場合も接続情報を変更したり、リソースを作成したりで面倒ですよね。

これらの問題を解決するためにBigQueryのエミュレータを使うことをおすすめします。

もう少し細かい説明

コンテナを利用しましょう

概要にはBigQueryのエミュレータの起動方法を記載しました。細かい使い方はこちらを御覧下さい。

利用する際はコンテナをおすすめします。こちらにgoを使ったバイナリインストールの方法がのっていますが、多分ビルドに時間がかかります。ここに単体テストと同一プロセスでBigQuery emulatorのサーバを立ち上げる方法が記載されていたのですが、ビルドに時間がかかってテストが起動できませんでした。多少古めのM1 Mac上でのビルドだったので、もっと新しいのならば実行可能かもしれませんが、一応、コンテナを使うことをおすすめしておきます。

BigQuery clientを使ったgolangの単体テスト

最後にBigQuery clientを使ったgolangの単体テストを書きます。

bigquery-emulatorは --data-from-yaml 引数でyamlファイルを渡すと、起動した時点でテーブルの作成と初期データの登録を行ってくれます。ただし、単体テストではテスト毎にデータベースは綺麗にしておきたいと思うので、テスト上でテーブル作成とデータ登録することをおすすめします。

テストを実行するまえに、bigquery-emulatorのコンテナを起動しておいてください。

以下にBigQuery clientでdataset、テーブルを作成するコードを記載します。

package main

import (
	"context"
	"testing"

	"cloud.google.com/go/bigquery"
	"google.golang.org/api/option"
)

type Data struct {
	IntData  int64  `bigquery:"int_data"`
	StrData  string `bigquery:"str_data"`
	JsonData string `bigquery:"json_data"`
}

func Test_UseBigQuery(t *testing.T) {
	ctx := context.Background()
	// Setup client.
	client, err := bigquery.NewClient(
		ctx,
		"test-proj",
		option.WithEndpoint("http://localhost:9050"),
		option.WithoutAuthentication(),
	)
	if err != nil {
		t.Fatal(err)
	}
	defer client.Close()

	// Create dataset.
	dataSet := client.Dataset("my_dataset")
	if err := dataSet.Create(ctx, nil); err != nil {
		t.Fatal(err)
	}
	defer dataSet.Delete(ctx)

	// Create table.
	table := dataSet.Table("my_table")
	if err := table.Create(ctx, &bigquery.TableMetadata{
		Schema: bigquery.Schema{
			{Name: "int_data", Type: bigquery.IntegerFieldType},
			{Name: "str_data", Type: bigquery.StringFieldType},
			{Name: "json_data", Type: bigquery.JSONFieldType},
		},
	}); err != nil {
		t.Fatal(err)
	}
	defer table.Delete(ctx)

	// Insert data.
	if _, err := client.Query(`INSERT INTO test-proj.my_dataset.my_table
        (int_data, str_data, json_data)
        VALUES (1, 'foo', JSON '{"bar": "baz"}')`).Read(ctx); err != nil {
		t.Fatal(err)
	}

	// Read data.
	iter, err := client.Query(`SELECT int_data, str_data, json_data FROM test-proj.my_dataset.my_table`).Read(ctx)
	if err != nil {
		t.Fatal(err)
	}
	m := Data{}
	err = iter.Next(&m)
	if err != nil {
		t.Fatal(err)
	}

	// Occur error to show what we got.
	t.Error(m)
}

まとめ

bigquery-emulatorを紹介し、コンテナの起動方法と単体テストの例を記載しました。

client作成部分からテーブル作成部分までを単体テストの例に記載しました。ここの部分を利用していただければbigquery-emulatorにアクセスする単体テストを実装できます。

今後は、テーブル作成までを実行するユーティリティ関数を作ってgithubに起きたいなとおもっています。

素晴しいソフトウフェアを作成して下さったgoccyさんに感謝です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?