You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用go-sqlmock模拟Ping命令?兼容*sql.DB的方案

模拟sql.DB.Ping() with go-sqlmock

Absolutely, you can simulate the Ping() method with go-sqlmock—even though there's no built-in ExpectPing() helper, the library gives you the flexibility to override the underlying driver's behavior to make this work. Here's how to do it properly:

Step 1: Override the Mock Driver's Ping Method

The sql.DB.Ping() call ultimately delegates to the underlying driver's Ping() method. go-sqlmock's MockDriver exposes this method directly, so you can replace it with your custom mock logic.

Here's a complete test example matching what you wanted:

import (
    "context"
    "errors"
    "testing"
    "github.com/DATA-DOG/go-sqlmock"
)

func TestDBPingMock(t *testing.T) {
    // Create the mock DB and mock instance
    db, mock, err := sqlmock.New()
    if err != nil {
        t.Fatalf("failed to initialize sqlmock: %v", err)
    }
    defer db.Close()

    // Mock the Ping behavior to return your desired error
    mock.Driver().Ping = func(ctx context.Context) error {
        return errors.New("mock error")
    }

    // Execute the Ping call
    err = db.Ping()
    if err == nil {
        t.Fatal("expected an error from Ping(), got nil instead")
    }

    // Verify all expectations (if you have other SQL expectations)
    if err := mock.ExpectationsWereMet(); err != nil {
        t.Fatalf("unfulfilled SQL expectations: %v", err)
    }
}

Step 2: Inject the Mock DB into Your New Function

Good news—this mock *sql.DB is fully compatible with the standard library's type, so you can pass it directly to any function that accepts a *sql.DB parameter. For example:

// Your existing New function
func New(db *sql.DB) *YourStruct {
    return &YourStruct{DB: db}
}

// In your test
testStruct := New(db) // Works perfectly with the sqlmock DB

Advanced: Simulate Dynamic Ping Behavior

If you need to mock varying Ping results (e.g., success on first call, failure on the second), you can use a closure to track state:

pingAttempts := 0
mock.Driver().Ping = func(ctx context.Context) error {
    pingAttempts++
    if pingAttempts == 1 {
        return nil // First Ping succeeds
    }
    return errors.New("mock failure on subsequent Pings")
}

Do You Need a Different Library?

Nope—go-sqlmock is fully capable of handling this use case. The lack of an ExpectPing() helper is just a missing convenience method, not a limitation of the library's core functionality. If you did want to explore alternatives, libraries like github.com/golang/mock paired with custom driver mocks work, but they're more verbose than the approach above.

Sticking with go-sqlmock is the simplest and most consistent choice here, since you're already using it for other database mocks.

内容的提问来源于stack exchange,提问作者dsncode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:22:32