メインコンテンツまでスキップ

Go 用 Databricks SQL ドライバー

Databricks SQLDriver for Go は、Go SQLコードを使用してDatabricks コンピュート リソースで コマンドを実行できるようにする Go ライブラリです。この記事では、Databricks SQL Driver for Go の README、API リファレンスおよび例を補足します。

必要条件

Databricks SQL Driver for Go の概要

  1. Go 1.20 以降が既にインストールされ、既存の Go コード プロジェクトが既に作成されている開発マシンで、次のように go mod init コマンドを実行して Go コードの依存関係を追跡するための go.mod ファイルを作成します。

    Bash
    go mod init sample
  2. go mod edit -require コマンドを実行し、リリースに記載されている最新バージョンの Databricks SQL Driver for Go パッケージv1.5.2に置き換えて、Databricks SQL Driver for Go パッケージに依存関係を取ります。

    Bash
    go mod edit -require github.com/databricks/databricks-sql-go@v1.5.2

    go.modファイルは次のようになります。

    Go
    module sample

    go 1.20

    require github.com/databricks/databricks-sql-go v1.5.2
  3. プロジェクトで、Go 用の Databricks SQL ドライバーをインポートする Go コード ファイルを作成します。 次の例では、次の内容の main.go という名前のファイルで、 Databricks ワークスペース内のすべてのクラスターが一覧表示されます。

    Go
    package main

    import (
    "database/sql"
    "os"
    _ "github.com/databricks/databricks-sql-go"
    )

    func main() {
    dsn := os.Getenv("DATABRICKS_DSN")

    if dsn == "" {
    panic("No connection string found. " +
    "Set the DATABRICKS_DSN environment variable, and try again.")
    }

    db, err := sql.Open("databricks", dsn)
    if err != nil {
    panic(err)
    }
    defer db.Close()

    if err := db.Ping(); err != nil {
    panic(err)
    }
    }
  4. 不足しているモジュールの依存関係を追加するには、 go mod tidy コマンドを実行します。

    Bash
    go mod tidy
注記

エラーが表示された場合 go: warning: "all" matched no packagesは、Go 用の Databricks SQL ドライバーをインポートする Go コード ファイルを追加するのを忘れていました。

  1. mainモジュール内のパッケージのビルドとテストをサポートするために必要なすべてのパッケージのコピーを作成するには、次のコマンドを実行してgo mod vendor

    Bash
    go mod vendor
  2. 必要に応じてコードを変更し、Databricks 認証DATABRICKS_DSN 環境変数を設定します。「DSN 接続文字列を使用した接続」も参照してください。

  3. main.goという名前のファイルを想定して、go run コマンドを実行して、Go コード ファイルを実行します。

    Bash
    go run main.go
  4. エラーが返されない場合は、 ワークスペースで Databricks SQLDriver for GoDatabricksDatabricksSQL が正常に認証され、そのワークスペース内の実行中の クラスターまたは ウェアハウスに接続されています。

DSN 接続文字列を使用して接続する

クラスターと SQLウェアハウスにアクセスするには、sql.Open() を使用して、データソース名 (DSN) 接続文字列を介してデータベースハンドルを作成します。 次のコード例では、 DATABRICKS_DSNという名前の環境変数から DSN 接続文字列を取得します。

Go
package main

import (
"database/sql"
"os"
_ "github.com/databricks/databricks-sql-go"
)

func main() {
dsn := os.Getenv("DATABRICKS_DSN")

if dsn == "" {
panic("No connection string found. " +
"Set the DATABRICKS_DSN environment variable, and try again.")
}

db, err := sql.Open("databricks", dsn)
if err != nil {
panic(err)
}
defer db.Close()

if err := db.Ping(); err != nil {
panic(err)
}
}

DSN 接続文字列を正しい形式で指定するには、「 認証」の DSN 接続文字列の例を参照してください。 たとえば、Databricks 個人用アクセス トークン認証の場合は、次の構文を使用します。

  • <personal-access-token> 要件からのあなたのDatabricks個人用アクセストークンです。
  • <server-hostname> は、 要件に含まれるサーバーのホスト名の値です
  • <port-number> は要件の ポート 値で、通常は 443です。
  • <http-path> は、 要件からの HTTP パスの値です
  • <paramX=valueX> は、この記事の後半に示す 1 つ以上の 省略可能なパラメーター です。
token:<personal-access-token>@<server-hostname>:<port-number>/<http-path>?<param1=value1>&

たとえば、クラスターの場合は次のようになります。

token:dapi12345678901234567890123456789012@1234567890123456.7.gcp.databricks.com:443/sql/protocolv1/o/1234567890123456/1234-567890-abcdefgh

たとえば、 SQLウェアハウスの場合、次のようになります。

token:dapi12345678901234567890123456789012@1234567890123456.7.gcp.databricks.com:443/sql/1.0/endpoints/a1b234c5678901d2
注記

セキュリティのベストプラクティスとして、このDSN接続文字列をGoコードにハードコードしないでください。 代わりに、この DSN 接続文字列を安全な場所から取得する必要があります。 たとえば、この記事で前述したコード例では、環境変数を使用しました。

省略可能なパラメーター

  • サポートされているオプションの接続パラメーターは、 <param=value>で指定できます。 より頻繁に使用されるものには、次のものがあります。

    • catalog: セッションの初期カタログ名を設定します。
    • schema: セッションの初期スキーマ名を設定します。
    • maxRows: リクエストごとに取得される最大行数を設定します。 デフォルトは 10000です。
    • timeout: サーバークエリ実行のタイムアウト (秒単位) を追加します。 デフォルトはタイムアウトなしです。
    • userAgentEntry: パートナーを識別するために使用されます。 詳細については、パートナーのドキュメントを参照してください。
  • サポートされているオプションのセッション パラメーターは、 param=valueで指定できます。 より頻繁に使用されるものには、次のものがあります。

    • ansi_mode: Boolean 文字列。 セッション・ステートメントが ANSI SQL 仕様で指定されたルールに従うためのtrue。システムのデフォルトは false です。
    • timezone: 文字列 (例: America/Los_Angeles. セッションのタイムゾーンを設定します。 システムのデフォルトは UTC です。

たとえば、 SQLウェアハウスの場合、次のようになります。

token:dapi12345678901234567890123456789012@1234567890123456.7.gcp.databricks.com:443/sql/1.0/endpoints/a1b234c5678901d2?catalog=hive_metastore&schema=example&maxRows=100&timeout=60&timezone=America/Sao_Paulo&ansi_mode=true

NewConnector機能で接続する

または、sql.OpenDB() を使用して、dbsql.NewConnector() で作成された新しいコネクタ オブジェクトを介してデータベース ハンドルを作成します (新しいコネクタ オブジェクトを使用して Databricks クラスターおよび SQLウェアハウスに接続するには、v1.0.0 以降の Databricks SQL Driver for Go が必要です)。 例えば:

Go
package main

import (
"database/sql"
"os"
dbsql "github.com/databricks/databricks-sql-go"
)

func main() {
connector, err := dbsql.NewConnector(
dbsql.WithAccessToken(os.Getenv("DATABRICKS_ACCESS_TOKEN")),
dbsql.WithServerHostname(os.Getenv("DATABRICKS_HOST")),
dbsql.WithPort(443),
dbsql.WithHTTPPath(os.Getenv("DATABRICKS_HTTP_PATH")),
)
if err != nil {
panic(err)
}

db := sql.OpenDB(connector)
defer db.Close()

if err := db.Ping(); err != nil {
panic(err)
}
}

NewConnector 設定の正しいセットを指定するには、認証の例を参照してください

注記

セキュリティのベストプラクティスとして、 NewConnector 設定をGoコードにハードコードしないでください。 代わりに、安全な場所からこれらの値を取得する必要があります。 たとえば、上記のコードでは環境変数が使用されています。

よく使われる機能オプションには、次のものがあります。

  • WithAccessToken(<access-token>): 要件からの Databricks 個人用アクセス トークン。 必須 string.
  • WithServerHostname(<server-hostname>): 要件の サーバーホスト名 の値。 必須 string.
  • WithPort(<port>): サーバーのポート番号、通常は 443。 必須 int
  • WithHTTPPath(<http-path>): 要件の HTTP パス 値。 必須 string.
  • WithInitialNamespace(<catalog>, <schema>) セッション内のカタログ名とスキーマ名。 オプションの string, string
  • WithMaxRows(<max-rows>): リクエストごとにフェッチされる最大行数。 デフォルトは 10000. オプション intです。
  • WithSessionParams(<params-map>): "timezone" と "ansi_mode" を含むセッション パラメーター。 オプションの map[string]string
  • WithTimeout(<timeout>).サーバークエリ実行のタイムアウト ( time.Duration単位)。 デフォルトはタイムアウトなしです。 随意。
  • WithUserAgentEntry(<isv-name-plus-product-name>).パートナーを識別するために使用されます。 詳細については、パートナーのドキュメントを参照してください。 オプションの string

例えば:

Go
connector, err := dbsql.NewConnector(
dbsql.WithAccessToken(os.Getenv("DATABRICKS_ACCESS_TOKEN")),
dbsql.WithServerHostname(os.Getenv("DATABRICKS_HOST")),
dbsql.WithPort(443),
dbsql.WithHTTPPath(os.Getenv("DATABRICKS_HTTP_PATH")),
dbsql.WithInitialNamespace("samples", "nyctaxi"),
dbsql.WithMaxRows(100),
dbsql.SessionParams(map[string]string{"timezone": "America/Sao_Paulo", "ansi_mode": "true"}),
dbsql.WithTimeout(time.Minute),
dbsql.WithUserAgentEntry("example-user"),
)

認証

Go 用 Databricks SQL ドライバーでは、次の Databricks 認証の種類がサポートされています。

Go 用 Databricks SQL ドライバーは、次の Databricks 認証の種類をまだサポートしていません。

Databricks 個人用アクセス トークン認証

Databricks 個人用アクセス トークン認証で Go 用 Databricks SQL ドライバーを使用するには、まず Databricks 個人用アクセス トークンを作成する必要があります。 この手順の詳細については、「 ワークスペース ユーザーの Databricks 個人用アクセス トークン」を参照してください。

DSN 接続文字列と「 DSN 接続文字列を使用した接続」のコード例を使用して Databricks SQL Driver for Go を認証するには、次の DSN 接続文字列構文を使用します。

  • <personal-access-token> 要件からのあなたのDatabricks個人用アクセストークンです。
  • <server-hostname> は、 要件に含まれるサーバーのホスト名の値です
  • <port-number> は要件の ポート 値で、通常は 443です。
  • <http-path> は、 要件からの HTTP パスの値です

また、この記事で前述した 1 つ以上の Optional パラメーター を追加することもできます。

token:<personal-access-token>@<server-hostname>:<port-number>/<http-path>

NewConnector 関数を使用して Go 用 Databricks SQL ドライバーを認証するには、次のコード スニペットと「NewConnector 関数との接続」のコード例を使用します。これは、次の環境変数が設定されていることを前提としています。

  • DATABRICKS_SERVER_HOSTNAMEクラスターまたはウェアハウスの Server Hostname 値 SQLに設定します。
  • DATABRICKS_HTTP_PATHで、クラスターまたはSQL ウェアハウスの HTTP パス 値に設定します。
  • DATABRICKS_TOKENで、Databricks 個人用アクセス トークンに設定されます。

環境変数を設定するには、ご利用になっているオペレーティングシステムのドキュメントを参照してください。

Go
connector, err := dbsql.NewConnector(
dbsql.WithServerHostname(os.Getenv("DATABRICKS_SERVER_HOSTNAME")),
dbsql.WithHTTPPath(os.Getenv("DATABRICKS_HTTP_PATH")),
dbsql.WithPort(443),
dbsql.WithAccessToken(os.Getenv("DATABRICKS_TOKEN")),
)

OAuth ユーザー間 (U2M) 認証

Databricks SQL Driver for Go バージョン 1.5.4 以降では 、OAuth ユーザー間 (U2M) 認証がサポートされています。

DSN 接続文字列と「 DSN 接続文字列を使用した接続」のコード例で Go 用 Databricks SQL ドライバーを使用するには、次の DSN 接続文字列構文を使用します。

  • <server-hostname> は、 要件に含まれるサーバーのホスト名の値です
  • <port-number> は要件の ポート 値で、通常は 443です。
  • <http-path> は、 要件からの HTTP パスの値です

また、この記事で前述した 1 つ以上の Optional パラメーター を追加することもできます。

<server-hostname>:<port-number>/<http-path>?authType=OauthU2M

NewConnector 関数を使用して Databricks SQL Driver for Go を認証するには、まず import 宣言に次のものを追加する必要があります。

Go
"github.com/databricks/databricks-sql-go/auth/oauth/u2m"

次に、次のコード スニペットと「NewConnector 関数を使用した接続」のコード例を使用します。これは、次の環境変数を設定していることを前提としています。

  • DATABRICKS_SERVER_HOSTNAMEクラスターまたはウェアハウスの Server Hostname 値 SQLに設定します。
  • DATABRICKS_HTTP_PATHで、クラスターまたはSQL ウェアハウスの HTTP パス 値に設定します。

環境変数を設定するには、ご利用になっているオペレーティングシステムのドキュメントを参照してください。

Go
authenticator, err := u2m.NewAuthenticator(os.Getenv("DATABRICKS_SERVER_HOSTNAME"), 1*time.Minute)
if err != nil {
panic(err)
}

connector, err := dbsql.NewConnector(
dbsql.WithServerHostname(os.Getenv("DATABRICKS_SERVER_HOSTNAME")),
dbsql.WithHTTPPath(os.Getenv("DATABRICKS_HTTP_PATH")),
dbsql.WithPort(443),
dbsql.WithAuthenticator(authenticator),
)

OAuth マシン間 (M2M) 認証

Databricks SQL Driver for Go バージョン 1.5.4 以降では、 OAuth マシン間 (M2M) 認証がサポートされています。

OAuth M2M 認証で Go 用 Databricks SQL ドライバーを使用するには、次の操作を行う必要があります。

  1. DatabricksワークスペースにDatabricks サービスプリンシパルを作成し、そのサービスプリンシパルのOAuthシークレットを作成します。

    サービスプリンシパルとそのOAuth シークレットを作成するには、「Databricksを使用してサービスプリンシパルを使用して リソースへの無人アクセスを承認OAuth する」を参照してください。サービスプリンシパルの UUID または Application ID の値と、サービスプリンシパルの シークレットの Secret OAuth 値をメモします。

  2. そのサービスプリンシパルに、クラスターまたはウェアハウスへのアクセス権を付与します。

    サービスプリンシパルにクラスターまたはウェアハウスへのアクセス権を付与するには、「コンピュートのアクセス許可」または「SQLウェアハウスの管理」を参照してください。

DSN 接続文字列と「 DSN 接続文字列を使用した接続」のコード例を使用して Databricks SQL Driver for Go を認証するには、次の DSN 接続文字列構文を使用します。

  • <server-hostname> は、 要件に含まれるサーバーのホスト名の値です
  • <port-number> は要件の ポート 値で、通常は 443です。
  • <http-path> は、 要件からの HTTP パスの値です
  • <client-id> は、サービスプリンシパルの UUID または アプリケーション ID の値です。
  • <client-secret> は、サービスプリンシパルの シークレットの Secret OAuth 値です。

また、この記事で前述した 1 つ以上の Optional パラメーター を追加することもできます。

<server-hostname>:<port-number>/<http-path>?authType=OAuthM2M&clientID=<client-id>&clientSecret=<client-secret>

NewConnector 関数を使用して Databricks SQL Driver for Go を認証するには、まず import 宣言に次のものを追加する必要があります。

Go
"github.com/databricks/databricks-sql-go/auth/oauth/m2m"

次に、次のコード スニペットと「NewConnector 関数を使用した接続」のコード例を使用します。これは、次の環境変数を設定していることを前提としています。

  • DATABRICKS_SERVER_HOSTNAMEクラスターまたはウェアハウスの Server Hostname 値 SQLに設定します。
  • DATABRICKS_HTTP_PATHで、クラスターまたはSQL ウェアハウスの HTTP パス 値に設定します。
  • DATABRICKS_CLIENT_IDで、サービスプリンシパルの UUID または アプリケーション ID の値に設定します。
  • DATABRICKS_CLIENT_SECRETで、サービスプリンシパルの OAuth シークレットの Secret 値に設定します。

環境変数を設定するには、ご利用になっているオペレーティングシステムのドキュメントを参照してください。

Go
authenticator := m2m.NewAuthenticator(
os.Getenv("DATABRICKS_CLIENT_ID"),
os.Getenv("DATABRICKS_CLIENT_SECRET"),
os.Getenv("DATABRICKS_SERVER_HOSTNAME"),
)

connector, err := dbsql.NewConnector(
dbsql.WithServerHostname(os.Getenv("DATABRICKS_SERVER_HOSTNAME")),
dbsql.WithHTTPPath(os.Getenv("DATABRICKS_HTTP_PATH")),
dbsql.WithPort(443),
dbsql.WithAuthenticator(authenticator),
)

データのクエリ

次のコード例は、Databricks SQL Driver for GoSQL Databricksを呼び出して、 コンピュート リソースに対する基本的な Microsoft クエリを実行する方法を示しています。このコマンドは、samples カタログの nyctaxi スキーマの trips テーブルから最初の 2 つのローを返します。

このコード例では、DATABRICKS_DSNという名前の環境変数から DSN 接続文字列を取得します。

Go
package main

import (
"database/sql"
"fmt"
"os"
"time"

_ "github.com/databricks/databricks-sql-go"
)

func main() {
dsn := os.Getenv("DATABRICKS_DSN")

if dsn == "" {
panic("No connection string found." +
"Set the DATABRICKS_DSN environment variable, and try again.")
}

db, err := sql.Open("databricks", dsn)
if err != nil {
panic(err)
}

defer db.Close()

var (
tpep_pickup_datetime time.Time
tpep_dropoff_datetime time.Time
trip_distance float64
fare_amount float64
pickup_zip int
dropoff_zip int
)

rows, err := db.Query("SELECT * FROM samples.nyctaxi.trips LIMIT 2")
if err != nil {
panic(err)
}

defer rows.Close()

fmt.Print("tpep_pickup_datetime,",
"tpep_dropoff_datetime,",
"trip_distance,",
"fare_amount,",
"pickup_zip,",
"dropoff_zip\n")

for rows.Next() {
err := rows.Scan(&tpep_pickup_datetime,
&tpep_dropoff_datetime,
&trip_distance,
&fare_amount,
&pickup_zip,
&dropoff_zip)
if err != nil {
panic(err)
}

fmt.Print(tpep_pickup_datetime, ",",
tpep_dropoff_datetime, ",",
trip_distance, ",",
fare_amount, ",",
pickup_zip, ",",
dropoff_zip, "\n")
}

err = rows.Err()
if err != nil {
panic(err)
}
}

Unity Catalog ボリューム内のファイルを管理する

Databricks SQL ドライバーを使用すると、次の例に示すように、Unity Catalog ボリュームへのローカル ファイルの書き込み、ボリュームからのファイルのダウンロード、ボリュームからのファイルの削除を行うことができます。

Go
package main

import (
"context"
"database/sql"
"os"

_ "github.com/databricks/databricks-sql-go"
"github.com/databricks/databricks-sql-go/driverctx"
)

func main() {
dsn := os.Getenv("DATABRICKS_DSN")

if dsn == "" {
panic("No connection string found." +
"Set the DATABRICKS_DSN environment variable, and try again.")
}

db, err := sql.Open("databricks", dsn)
if err != nil {
panic(err)
}
defer db.Close()

// For writing local files to volumes and downloading files from volumes,
// you must first specify the path to the local folder that contains the
// files to be written or downloaded.
// For multiple folders, add their paths to the following string array.
// For deleting files in volumes, this string array is ignored but must
// still be provided, so in that case its value can be set for example
// to an empty string.
ctx := driverctx.NewContextWithStagingInfo(
context.Background(),
[]string{"/tmp/"},
)

// Write a local file to the path in the specified volume.
// Specify OVERWRITE to overwrite any existing file in that path.
db.ExecContext(ctx, "PUT '/tmp/my-data.csv' INTO '/Volumes/main/default/my-volume/my-data.csv' OVERWRITE")

// Download a file from the path in the specified volume.
db.ExecContext(ctx, "GET '/Volumes/main/default/my-volume/my-data.csv' TO '/tmp/my-downloaded-data.csv'")

// Delete a file from the path in the specified volume.
db.ExecContext(ctx, "REMOVE '/Volumes/main/default/my-volume/my-data.csv'")

db.Close()
}

伐採

github.com/databricks/databricks-sql-go/logger を使用して、Databricks SQL Driver for Go が出力するメッセージをログに記録します。次のコード例では、 sql.Open() を使用して、DSN 接続文字列を介してデータベース ハンドルを作成します。 このコード例では、 DATABRICKS_DSNという名前の環境変数から DSN 接続文字列を取得します。 debug レベル以下で出力されるすべてのログ メッセージは、results.log ファイルに書き込まれます。

Go
package main

import (
"database/sql"
"io"
"log"
"os"

_ "github.com/databricks/databricks-sql-go"
dbsqllog "github.com/databricks/databricks-sql-go/logger"
)

func main() {
dsn := os.Getenv("DATABRICKS_DSN")

// Use the specified file for logging messages to.
file, err := os.Create("results.log")
if err != nil {
log.Fatal(err)
}
defer file.Close()

writer := io.Writer(file)

// Log messages at the debug level and below.
if err := dbsqllog.SetLogLevel("debug"); err != nil {
log.Fatal(err)
}

// Log messages to the file.
dbsqllog.SetLogOutput(writer)

if dsn == "" {
panic("Error: Cannot connect. No connection string found. " +
"Set the DATABRICKS_DSN environment variable, and try again.")
}

db, err := sql.Open("databricks", dsn)
if err != nil {
panic(err)
}
defer db.Close()

if err := db.Ping(); err != nil {
panic(err)
}
}

テスティング

コードをテストするには、 テスト 標準ライブラリなどの Go テストフレームワークを使用します。 Databricks REST API エンドポイントを呼び出したり、Databricks アカウントやワークスペースの状態を変更したりせずに、シミュレートされた条件下でコードをテストするには、 testfify などの Go モック ライブラリを使用します。

たとえば、Databricks ワークスペース接続を返す GetDBWithDSNPAT 関数、samples カタログの nyctaxi スキーマの trips テーブルからデータを返す GetNYCTaxiTrips 関数、および返されたデータを出力するPrintNYCTaxiTripsを含む 、helpers.go という名前の次のファイルがあるとします。

Go
package main

import (
"database/sql"
"fmt"
"strconv"
"time"
)

func GetDBWithDSNPAT(dsn string) (*sql.DB, error) {
db, err := sql.Open("databricks", dsn)
if err != nil {
return nil, err
}
return db, nil
}

func GetNYCTaxiTrips(db *sql.DB, numRows int) (*sql.Rows, error) {
rows, err := db.Query("SELECT * FROM samples.nyctaxi.trips LIMIT " + strconv.Itoa(numRows))
if err != nil {
return nil, err
}
return rows, nil
}

func PrintNYCTaxiTrips(rows *sql.Rows) {
var (
tpep_pickup_datetime time.Time
tpep_dropoff_datetime time.Time
trip_distance float64
fare_amount float64
pickup_zip int
dropoff_zip int
)

fmt.Print(
"tpep_pickup_datetime,",
"tpep_dropoff_datetime,",
"trip_distance,",
"fare_amount,",
"pickup_zip,",
"dropoff_zip\n",
)

for rows.Next() {
err := rows.Scan(
&tpep_pickup_datetime,
&tpep_dropoff_datetime,
&trip_distance,
&fare_amount,
&pickup_zip,
&dropoff_zip,
)
if err != nil {
panic(err)
}

fmt.Print(
tpep_pickup_datetime, ",",
tpep_dropoff_datetime, ",",
trip_distance, ",",
fare_amount, ",",
pickup_zip, ",",
dropoff_zip, "\n",
)
}

err := rows.Err()
if err != nil {
panic(err)
}
}

そして、これらの関数を呼び出す main.go という名前の次のファイルがあるとします。

Go
package main

import (
"os"
)

func main() {
db, err := GetDBWithDSNPAT(os.Getenv("DATABRICKS_DSN"))
if err != nil {
panic(err)
}

rows, err := GetNYCTaxiTrips(db, 2)
if err != nil {
panic(err)
}

PrintNYCTaxiTrips(rows)
}

次の helpers_test.go という名前のファイルは、 GetNYCTaxiTrips 関数が予期した応答を返すかどうかをテストします。 このテストでは、ターゲット ワークスペースへの実際の接続を作成するのではなく、 sql.DB オブジェクトをモックします。 また、このテストでは、実際のデータにあるスキーマと値に準拠する一部のデータをモックします。 このテストでは、モックされた接続を介してモックされたデータが返され、モックされたデータ行の値の 1 つが期待値と一致するかどうかがチェックされます。

Go
package main

import (
"database/sql"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)

// Define an interface that contains a method with the same signature
// as the real GetNYCTaxiTrips function that you want to test.
type MockGetNYCTaxiTrips interface {
GetNYCTaxiTrips(db *sql.DB, numRows int) (*sql.Rows, error)
}

// Define a struct that represents the receiver of the interface's method
// that you want to test.
type MockGetNYCTaxiTripsObj struct {
mock.Mock
}

// Define the behavior of the interface's method that you want to test.
func (m *MockGetNYCTaxiTripsObj) GetNYCTaxiTrips(db *sql.DB, numRows int) (*sql.Rows, error) {
args := m.Called(db, numRows)
return args.Get(0).(*sql.Rows), args.Error(1)
}

func TestGetNYCTaxiTrips(t *testing.T) {
// Instantiate the receiver.
mockGetNYCTaxiTripsObj := new(MockGetNYCTaxiTripsObj)

// Define how the mock function should be called and what it should return.
// We're not concerned with whether the actual database is connected to--just
// what is returned.
mockGetNYCTaxiTripsObj.On("GetNYCTaxiTrips", mock.Anything, mock.AnythingOfType("int")).Return(&sql.Rows{}, nil)

// Call the mock function that you want to test.
rows, err := mockGetNYCTaxiTripsObj.GetNYCTaxiTrips(nil, 2)

// Assert that the mock function was called as expected.
mockGetNYCTaxiTripsObj.AssertExpectations(t)

// Assert that the mock function returned what you expected.
assert.NotNil(t, rows)
assert.Nil(t, err)
}

GetNYCTaxiTrips 関数には SELECT ステートメントが含まれているため、trips テーブルの状態は変更されないため、この例ではモックは絶対に必要ではありません。ただし、モックを使用すると、ワークスペースとの実際の接続を待たずに、テストをすばやく実行できます。 また、モックを使用すると、テーブルの状態を変更する可能性のある関数 ( 、 、 INSERT INTOUPDATEDELETE FROMなど) のシミュレートされたテストを複数回実行できます。

追加のリソース