Mocking database return types with interfaces

Viewed 781

How to correctly mock some *sql.DB methods for unit testing using interfaces? For example, I want to have a Store struct that is used as a datasource for my handlers. It has a conn field that is the *sql.DB. But in my tests I want to mock the DB, so I try to return not the actual *sql.Rows but an interface that the *sql.Rows should satisfy. Here is the code:

type TestRows interface {
    Scan ()
}

type TestDB interface {
    Query (query string, args ...interface{}) (TestRows, error) 
}

type Rows struct {
    //..
}

func (r *Rows) Scan () {
    fmt.Println("Scanning")
}

This is the *sql.DB

type DB struct {
    //...
}

func (d *DB) Query (query string, args ...inteface{}) (*Rows, error) {
    return &Rows{/* .... */}, nil
}

And when I want to instantiate the Store, it throws error

type Store struct {
    conn TestDB
}

func main() { 
    cl := Store {conn: &DB{}}
    fmt.Println("Hello, playground")
}

cannot use DB literal (type *DB) as type TestDB in field value:
    *DB does not implement TestDB (wrong type for Query method)
        have Query(string) (*Rows, error)
        want Query(string) (TestRows, error)
2 Answers
Related