Pular para o conteúdo principal

Databricks SQL Driver para Go

O Databricks SQL Driver for Go é uma biblioteca Go que permite que o senhor use o código Go para executar SQL comando em Databricks compute recurso. Este artigo complementa o Databricks SQL Driver for Go README, a referênciaAPI e os exemplos.

Requisitos

Começar a usar o driver Databricks SQL para Go

  1. Em sua máquina de desenvolvimento com o Go 1.20 ou acima já instalado e um projeto de código Go existente já criado, crie um arquivo go.mod para rastrear as dependências do seu código Go executando o comando go mod init, por exemplo:

    Bash
    go mod init sample
  2. Dependa do pacote Databricks SQL Driver for Go executando o comando go mod edit -require, substituindo v1.5.2 pela versão mais recente do pacote Databricks SQL Driver for Go, conforme listado em Releases:

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

    Seu arquivo go.mod agora deve ter a seguinte aparência:

    Go
    module sample

    go 1.20

    require github.com/databricks/databricks-sql-go v1.5.2
  3. Em seu projeto, crie um arquivo de código Go que importe o Databricks SQL Driver for Go. O exemplo a seguir, em um arquivo chamado main.go com o seguinte conteúdo, lista todos os clusters em seu site Databricks workspace:

    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. Adicione as dependências de módulo ausentes executando o comando go mod tidy:

    Bash
    go mod tidy
nota

Se receber o erro go: warning: "all" matched no packages, o senhor esqueceu de adicionar um arquivo de código Go que importa o Databricks SQL Driver for Go.

  1. Faça cópias de todo o pacote necessário para dar suporte a compilações e testes do pacote em seu módulo main, executando o comando go mod vendor:

    Bash
    go mod vendor
  2. Modifique seu código conforme necessário para definir a variável de ambiente DATABRICKS_DSN para autenticação do Databricks. Consulte também Conectar com uma cadeia de conexão DSN.

  3. Execute seu arquivo de código Go, supondo que seja um arquivo chamado main.go, executando o comando go run:

    Bash
    go run main.go
  4. Se nenhum erro for retornado, o senhor autenticou com sucesso o Databricks SQL Driver for Go com seu Databricks workspace e se conectou ao seu clustering Databricks em execução ou SQL warehouse nesse workspace.

Conectar-se com uma string de conexão DSN

Para acessar o armazenamento em cluster e SQL, use sql.Open() para criar um identificador de banco de dados por meio de uma fonte de dados name (DSN) connection strings. Este exemplo de código recupera as cadeias de conexão DSN de uma variável de ambiente chamada DATABRICKS_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)
}
}

Para especificar as cadeias de conexão DSN no formato correto, consulte os exemplos de cadeias de conexão DSN em Autenticação. Por exemplo, para autenticação de tokens de acesso pessoal Databricks, use a seguinte sintaxe, onde

  • <personal-access-token> é o seu Databricks tokens de acesso pessoal dos requisitos.
  • <server-hostname> é o valor do nome do host do servidor a partir dos requisitos.
  • <port-number> é o valor da porta dos requisitos, que normalmente é 443.
  • <http-path> é o valor do caminho HTTP dos requisitos.
  • <paramX=valueX> é um ou mais parâmetros opcionais listados posteriormente neste artigo.
token:<personal-access-token>@<server-hostname>:<port-number>/<http-path>?<param1=value1>&

Por exemplo, para um clustering:

token:dapi12345678901234567890123456789012@dbc-a1b2345c-d6e7.cloud.databricks.com:443/sql/protocolv1/o/1234567890123456/1234-567890-abcdefgh

Por exemplo, para um SQL warehouse:

token:dapi12345678901234567890123456789012@dbc-a1b2345c-d6e7.cloud.databricks.com:443/sql/1.0/endpoints/a1b234c5678901d2
nota

Como prática recomendada de segurança, o senhor não deve codificar essas strings de conexão DSN no seu código Go. Em vez disso, o senhor deve recuperar essas cadeias de conexão DSN de um local seguro. Por exemplo, o exemplo de código anterior neste artigo usou uma variável de ambiente.

Parâmetros opcionais

  • Os parâmetros de conexão opcionais suportados podem ser especificados em <param=value>. Alguns dos usados com mais frequência incluem:

    • catalog: define o nome inicial do catálogo na sessão.
    • schema: define o nome inicial do esquema na sessão.
    • maxRows: configura o número máximo de linhas buscadas por solicitação. O endereço default é 10000.
    • timeout: adiciona o tempo limite (em segundos) para a execução da consulta do servidor. O site default não tem tempo limite.
    • userAgentEntry: Usado para identificar parceiros. Para obter mais informações, consulte a documentação de seu parceiro.
  • Os parâmetros de sessão opcionais suportados podem ser especificados em param=value. Alguns dos usados com mais frequência incluem:

    • ansi_mode: A Boolean strings. true para que as instruções de sessão sigam as regras especificadas pela especificação ANSI SQL. O sistema default é falso.
    • timezone: A strings, por exemplo, America/Los_Angeles. Define o fuso horário da sessão. O sistema default é UTC.

Por exemplo, para um SQL warehouse:

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

Conecte-se com a função NewConnector

Como alternativa, use sql.OpenDB() para criar um identificador de banco de dados por meio de um novo objeto de conector criado com dbsql.NewConnector() (a conexão com o Databricks clustering e o SQL warehouse com um novo objeto de conector requer a versão 1.0.0 ou superior do driver Databricks SQL para Go). Por exemplo:

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)
}
}

Para especificar o conjunto correto de configurações NewConnector, consulte os exemplos em Autenticação.

nota

Como prática recomendada de segurança, você não deve codificar suas configurações NewConnector em seu código Go. Em vez disso, você deve recuperar esses valores de um local seguro. Por exemplo, o código anterior usa variável de ambiente.

Algumas das opções funcionais usadas com mais frequência incluem:

  • WithAccessToken(<access-token>): Seu Databricks tokens de acesso pessoal dos requisitos. Obrigatório string.
  • WithServerHostname(<server-hostname>): o valor do nome do host do servidor a partir dos requisitos. Obrigatório string.
  • WithPort(<port>): o número da porta do servidor, normalmente 443. Obrigatório int.
  • WithHTTPPath(<http-path>): o valor do caminho HTTP dos requisitos. Obrigatório string.
  • WithInitialNamespace(<catalog>, <schema>) nome do catálogo e do esquema na sessão. Opcional string, string.
  • WithMaxRows(<max-rows>): o número máximo de linhas buscadas por solicitação. O endereço default é 10000. Opcional int.
  • WithSessionParams(<params-map>): os parâmetros da sessão, incluindo “timezone” e “ansi_mode”. Opcional map[string]string.
  • WithTimeout(<timeout>). O tempo limite (em time.Duration) para a execução da consulta do servidor. O site default não tem tempo limite. Opcional.
  • WithUserAgentEntry(<isv-name-plus-product-name>). Usado para identificar parceiros. Para obter mais informações, consulte a documentação de seu parceiro. Opcional string.

Por exemplo:

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"),
)

Autenticação

O Databricks SQL Driver for Go suporta os seguintes tipos de autenticação Databricks:

Databricks autenticação de tokens de acesso pessoal

Para usar o Databricks SQL driver para Go com Databricks autenticação de tokens de acesso pessoal, o senhor deve primeiro criar um Databricks token de acesso pessoal. Para obter detalhes sobre essa etapa, consulte Databricks personal access tokens for workspace users.

Para autenticar o driver Databricks SQL para Go com uma cadeia de conexão DSN e o exemplo de código em Conectar com uma cadeia de conexão DSN, use a seguinte sintaxe de cadeia de conexão DSN, onde

  • <personal-access-token> é o seu Databricks tokens de acesso pessoal dos requisitos.
  • <server-hostname> é o valor do nome do host do servidor a partir dos requisitos.
  • <port-number> é o valor da porta dos requisitos, que normalmente é 443.
  • <http-path> é o valor do caminho HTTP dos requisitos.

O senhor também pode anexar um ou mais parâmetros Optional listados anteriormente neste artigo.

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

Para autenticar o driver Databricks SQL para Go com a função NewConnector, use o seguinte trecho de código e o exemplo de código em Connect com a função NewConnector, que pressupõe que o senhor tenha definido a seguinte variável de ambiente:

  • DATABRICKS_SERVER_HOSTNAMEdefinido como o valor do Server Hostname para seu clustering ou SQL warehouse.
  • DATABRICKS_HTTP_PATHDefina o valor do caminho HTTP para seu clustering ou SQL warehouse.
  • DATABRICKS_TOKEN, definido como os tokens de acesso pessoal Databricks.

Para definir variáveis de ambiente, consulte a documentação do sistema operacional.

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")),
)

Autenticação OAuth de usuário para máquina (U2M)

Databricks SQL As versões 1.5.0 e acima do Driver for Go suportam a autenticaçãoOAuth user-to-machine (U2M).

Para usar o driver Databricks SQL para Go com cadeias de conexão DSN e o exemplo de código em Conectar com cadeias de conexão DSN, use a seguinte sintaxe de cadeias de conexão DSN, onde

  • <server-hostname> é o valor do nome do host do servidor a partir dos requisitos.
  • <port-number> é o valor da porta dos requisitos, que normalmente é 443.
  • <http-path> é o valor do caminho HTTP dos requisitos.

O senhor também pode anexar um ou mais parâmetros Optional listados anteriormente neste artigo.

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

Para autenticar o Databricks SQL Driver for Go com a função NewConnector, o senhor deve primeiro adicionar o seguinte à sua declaração import:

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

Em seguida, use o seguinte trecho de código e o exemplo de código em Connect com a função NewConnector, que pressupõe que o senhor tenha definido a seguinte variável de ambiente:

  • DATABRICKS_SERVER_HOSTNAMEdefinido como o valor do Server Hostname para seu clustering ou SQL warehouse.
  • DATABRICKS_HTTP_PATHDefina o valor do caminho HTTP para seu clustering ou SQL warehouse.

Para definir variáveis de ambiente, consulte a documentação do sistema operacional.

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),
)

Autenticação OAuth máquina a máquina (M2M)

Databricks SQL As versões 1.5.2 e acima do Driver for Go suportam a autenticação máquina a máquina (M2M)OAuth.

Para usar o Databricks SQL Driver for Go com a autenticação OAuth M2M, o senhor deve fazer o seguinte:

  1. Crie uma Databricks entidade de serviço em seu Databricks workspace e crie um OAuth secret para essa entidade de serviço.

    Para criar a entidade de serviço e seu segredo OAuth, consulte Autorizar o acesso autônomo a Databricks recurso com uma entidade de serviço usando OAuth. Anote o valor do UUID da entidade de serviço ou do ID do aplicativo e o valor do segredo do OAuth da entidade de serviço.

  2. Dê a essa entidade de serviço acesso ao seu clustering ou depósito.

    Para conceder à entidade de serviço acesso ao seu clustering ou warehouse, consulte compute permissions ou gerenciar a SQL warehouse.

Para autenticar o driver Databricks SQL para Go com uma cadeia de conexão DSN e o exemplo de código em Conectar com uma cadeia de conexão DSN, use a seguinte sintaxe de cadeia de conexão DSN, onde

  • <server-hostname> é o valor do nome do host do servidor a partir dos requisitos.
  • <port-number> é o valor da porta dos requisitos, que normalmente é 443.
  • <http-path> é o valor do caminho HTTP dos requisitos.
  • <client-id> é o UUID da entidade de serviço ou o valor do ID do aplicativo .
  • <client-secret> é o valor de Secret para o segredo OAuth da entidade de serviço.

O senhor também pode anexar um ou mais parâmetros Optional listados anteriormente neste artigo.

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

Para autenticar o Databricks SQL Driver for Go com a função NewConnector, o senhor deve primeiro adicionar o seguinte à sua declaração import:

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

Em seguida, use o seguinte trecho de código e o exemplo de código em Connect com a função NewConnector, que pressupõe que o senhor tenha definido a seguinte variável de ambiente:

  • DATABRICKS_SERVER_HOSTNAMEdefinido como o valor do Server Hostname para seu clustering ou SQL warehouse.
  • DATABRICKS_HTTP_PATHDefina o valor do caminho HTTP para seu clustering ou SQL warehouse.
  • DATABRICKS_CLIENT_IDdefinido como o valor do UUID da entidade de serviço ou do ID do aplicativo .
  • DATABRICKS_CLIENT_SECRETdefinido como o valor Secret do segredo OAuth da entidade de serviço.

Para definir variáveis de ambiente, consulte a documentação do sistema operacional.

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),
)

Dados de consulta

O exemplo de código a seguir demonstra como chamar o driver Databricks SQL para o Go para executar uma consulta básica SQL em um recurso Databricks compute . Esse comando retorna as duas primeiras linhas da tabela trips no esquema nyctaxi do catálogo samples.

Este exemplo de código recupera as cadeias de conexão DSN de uma variável de ambiente chamada DATABRICKS_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)
}
}

Gerenciar arquivos em Unity Catalog volumes

O Databricks SQL driver permite que o senhor grave arquivos locais em Unity Catalog volumes, download arquivos de volumes e exclua arquivos de volumes, conforme mostrado no exemplo a seguir:

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()
}

Registro

Use github.com/databricks/databricks-sql-go/logger para log mensagens que o driver Databricks SQL para Go emite. O exemplo de código a seguir usa o site sql.Open() para criar um identificador de banco de dados por meio de uma string de conexão DSN. Este exemplo de código recupera as cadeias de conexão DSN de uma variável de ambiente chamada DATABRICKS_DSN. Todas as mensagens do site log emitidas no nível debug e abaixo são gravadas no arquivo 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)
}
}

Testando

Para testar seu código, use estruturas de teste em Go, como a biblioteca padrão de testes. Para testar seu código em condições simuladas sem chamar o endpoint Databricks REST API ou alterar o estado de sua conta ou espaço de trabalho Databricks, use a biblioteca de simulação Go, como o testfify.

Por exemplo, dado o seguinte arquivo denominado helpers.go contendo uma função GetDBWithDSNPAT que retorna uma conexão Databricks workspace , uma função GetNYCTaxiTrips que retorna dados da tabela trips no esquema nyctaxi do catálogo samples e uma PrintNYCTaxiTrips que imprime os dados retornados:

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)
}
}

E dado o seguinte arquivo chamado main.go que chama essas funções:

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)
}

O arquivo a seguir chamado helpers_test.go testa se a função GetNYCTaxiTrips retorna a resposta esperada. Em vez de criar uma conexão real com o destino workspace, esse teste simula um objeto sql.DB. O teste também simula alguns dados que estão em conformidade com o esquema e os valores que estão nos dados reais. O teste retorna os dados simulados por meio da conexão simulada e, em seguida, verifica se um dos valores das linhas de dados simuladas corresponde ao valor esperado.

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)
}

Como a função GetNYCTaxiTrips contém uma instrução SELECT e, portanto, não altera o estado da tabela trips, a simulação não é absolutamente necessária neste exemplo. No entanto, o mocking permite que o senhor execute rapidamente seus testes sem esperar que seja feita uma conexão real com o site workspace. Além disso, o mocking permite que o senhor execute testes simulados várias vezes para funções que possam alterar o estado de uma tabela, como INSERT INTO, UPDATE e DELETE FROM.

Recurso adicional