DATA-DOG / go-sqlmock

Sql mock driver for golang to test database interactions
Other
6.02k stars 406 forks source link

Operations on go-sqlmock.Driver fail with: expected a connection to be available, but it is not #267

Open fho opened 3 years ago

fho commented 3 years ago

Hello,

I'm working on a package that wraps an sql.Driver and adds functionality. To test it, I'm trying to use go-sqlmock. I'm running into the issue that if I wrap the go-sqlmock Driver, all operations fail with the error: expected a connection to be available, but it is not

I'm accessing the driver via:

db, _, _ := sqlmock.New()
db.Driver()

This can be reproduced e.g. via sqlmw:

package dddbmock_test

import (
    "database/sql"
    "testing"

    "github.com/DATA-DOG/go-sqlmock"
    "github.com/ngrok/sqlmw"
)

func TestMWWrap(t *testing.T) {
    db, _, err := sqlmock.New()
    if err != nil {
        t.Fatal("sqlmock new failed:", err)
    }

    sql.Register(
        "mwdriver",
        sqlmw.Driver(db.Driver(), &sqlmw.NullInterceptor{}),
    )

    db, err = sql.Open("mydriver", "")
    if err != nil {
        t.Fatal("opening driver failed:", err)
    }

    if err := db.Ping(); err != nil {
        t.Error("ping failed", err)
    }
}

Without using other external packages and mimicking the wrapping behavior instead it can be reproduced like:

package dddbmock_test

import (
    "database/sql"
    "testing"

    "github.com/DATA-DOG/go-sqlmock"
)

func TestRegister(t *testing.T) {
    db, _, err := sqlmock.New(sqlmock.MonitorPingsOption(true))
    if err != nil {
        t.Fatal("sqlmock new failed:", err)
    }

    sql.Register("mydriver", db.Driver())

    db, err = sql.Open("mydriver", "")
    if err != nil {
        t.Fatal("opening driver failed:", err)
    }

    if err := db.Ping(); err != nil {
        t.Error("ping failed", err)
    }

    if _, err := db.Exec(""); err != nil {
        t.Error("exec failed", err)
    }
}

The comment https://github.com/DATA-DOG/go-sqlmock/issues/83#issuecomment-582962456 seems to be about the same issue. I guess it's not intended to be used like that, but it would be awesome to support operations on the go-sqlmock Driver.

l3pp4rd commented 3 years ago

Hi, maybe you are willing to contribute this patch? Haven’t used golang for more than a year, would be difficult to find a willing to

fho commented 3 years ago

@l3pp4rd depends on the effort :-). I ended up writing my own simple mock instead, that works okayish for my current usecase. Do you maybe have an idea what the cause it how it could be fixed?

dolmen commented 2 years ago

The first code has a typo in the driver name: mwdriver vs mydriver.

dolmen commented 2 years ago

Here is a hack (unsupported): use the internal DSN:

db, err = sql.Open("mydriver", "sqlmock_db_0")

Example on the Go Playground