如何在Golang中为BigQuery查询编写集成测试?
Golang中BigQuery查询表数据的集成测试实现
针对BigQuery的集成测试,推荐使用BigQuery模拟器(无需真实GCP资源,零成本且环境隔离)或专用测试GCP项目。以下是基于模拟器的查询表数据集成测试实现:
测试代码实现
package yourpackage import ( "context" "fmt" "testing" "time" "cloud.google.com/go/bigquery" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/modules/bigquery" "google.golang.org/api/iterator" ) func TestQueryBigQueryTable(t *testing.T) { t.Parallel() // 初始化上下文 ctx := context.Background() // 启动BigQuery模拟器容器(自动管理生命周期) bqContainer, err := bigquery.StartContainer(ctx, testcontainers.WithImage("gcr.io/cloud-spanner-emulator/bigquery-emulator:latest")) if err != nil { t.Fatalf("启动BigQuery模拟器失败: %v", err) } // 测试结束后终止容器 t.Cleanup(func() { if err := bqContainer.Terminate(ctx); err != nil { t.Fatalf("终止BigQuery模拟器失败: %v", err) } }) // 创建连接到模拟器的BigQuery客户端 client, err := bigquery.NewClient(ctx, "test-project-id", bigquery.WithEndpoint(bqContainer.Endpoint)) if err != nil { t.Fatalf("创建BigQuery客户端失败: %v", err) } defer client.Close() // 创建测试数据集 datasetID := "test_dataset" dataset := client.Dataset(datasetID) if err := dataset.Create(ctx, nil); err != nil { t.Fatalf("创建数据集失败: %v", err) } // 测试结束后删除数据集及内容 t.Cleanup(func() { if err := dataset.Delete(ctx, bigquery.DeleteContents()); err != nil { t.Fatalf("删除数据集失败: %v", err) } }) // 创建测试表并定义Schema tableID := "test_table" schema := bigquery.Schema{ {Name: "id", Type: bigquery.IntegerFieldType, Required: true}, {Name: "name", Type: bigquery.StringFieldType, Required: true}, {Name: "created_at", Type: bigquery.TimestampFieldType, Required: true}, } table := dataset.Table(tableID) if err := table.Create(ctx, &bigquery.TableMetadata{Schema: schema}); err != nil { t.Fatalf("创建测试表失败: %v", err) } // 插入测试数据 testRows := []*bigquery.StructSaver{ {Struct: struct { ID int64 Name string CreatedAt time.Time }{ID: 1, Name: "Alice", CreatedAt: time.Now()}, Schema: schema}, {Struct: struct { ID int64 Name string CreatedAt time.Time }{ID: 2, Name: "Bob", CreatedAt: time.Now()}, Schema: schema}, } if _, err := table.Uploader().Put(ctx, testRows); err != nil { t.Fatalf("插入测试数据失败: %v", err) } // 执行目标查询 query := client.Query(fmt.Sprintf(` SELECT id, name FROM %s.%s WHERE id > 0 `, datasetID, tableID)) job, err := query.Run(ctx) if err != nil { t.Fatalf("执行查询失败: %v", err) } // 读取查询结果 resultIter, err := job.Read(ctx) if err != nil { t.Fatalf("读取查询结果失败: %v", err) } // 解析并验证结果 var retrievedRows []struct { ID int64 `bigquery:"id"` Name string `bigquery:"name"` } for { var row struct { ID int64 `bigquery:"id"` Name string `bigquery:"name"` } err := resultIter.Next(&row) if err == iterator.Done { break } if err != nil { t.Fatalf("遍历结果失败: %v", err) } retrievedRows = append(retrievedRows, row) } // 断言结果符合预期 if len(retrievedRows) != 2 { t.Fatalf("预期2条数据,实际得到%d条", len(retrievedRows)) } if retrievedRows[0].ID != 1 || retrievedRows[0].Name != "Alice" { t.Fatalf("第一条数据不符合预期: %+v", retrievedRows[0]) } if retrievedRows[1].ID != 2 || retrievedRows[1].Name != "Bob" { t.Fatalf("第二条数据不符合预期: %+v", retrievedRows[1]) } }
关键说明
- 依赖安装:执行以下命令安装所需依赖
go get cloud.google.com/go/bigquery github.com/testcontainers/testcontainers-go github.com/testcontainers/testcontainers-go/modules/bigquery - 手动启动模拟器替代方案:若不想用Testcontainers,可手动启动BigQuery模拟器,设置环境变量
BIGQUERY_EMULATOR_HOST,客户端会自动连接,无需指定WithEndpoint - 真实GCP项目适配:替换
test-project-id为你的测试项目ID,确保测试账号拥有BigQuery数据集/表的读写权限,测试后及时清理资源避免产生费用 - 资源自动清理:使用
t.Cleanup()确保测试后自动清理模拟器、数据集和表,避免环境污染
内容的提问来源于stack exchange,提问作者Yuseferi
相关产品推荐
相关产品推荐

