jeudi 13 septembre 2018

Mocking go methods

I'm writing a small POC in go for work, but I can't seem to figure out the mocking techniques. this is what I have so far...

connect.go

package db

import (
    "database/sql"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "strings"

    _ "github.com/lib/pq"
)

type config map[string]interface{}

type DbConn struct {
    db db
}

type db interface {
    getConnectionStringFromConfig(file string) (connStr string, err error)
}

func NewDbConn(d db) *DbConn {
    return &DbConn{db: d}
}

func getConnectionStringFromConfig(file string) (connStr string, err error) {
    var c config
    var bt []byte
    if bt, err = ioutil.ReadFile(file); err != nil {
        fmt.Printf("Error Reading config file: %v", err)
        return
    }
    fmt.Println("Finish reading file. Going to construct a connection string")
    if err = json.Unmarshal(bt, &c); err != nil {
        fmt.Printf("Error unmarshalling config file: %v", err)
        return
    }
    connStr = strings.TrimLeft(getConfigAsString(c), " ")
    return
}

func getConfigAsString(c config) (connStr string) {
    for k, v := range c {
        connStr += strings.Join([]string{" " + k, v.(string)}, "=")
    }
    return
}

// Connect database connection
func (dbConn DbConn) Connect() (conn *sql.DB, err error) {
    fmt.Println("Starting database connection...")
    connStr, err := getConnectionStringFromConfig("path/to/conf.json")
    if err != nil {
        return
    }
    conn, err = sql.Open("some_driver", connStr)
    return
}

connect_test.go

package db

import (
    "errors"
    "testing"
)

type dbConnMock struct {
    db dbMock
}

type dbMock interface {
    getConnectionStringFromConfig(file string) (connStr string, err error)
}

func (dbm dbConnMock) getConnectionStringFromConfig(file string) (connStr string, err error) {
    return "", errors.New("123")
}

// should not throw error when trying to open db connection
func TestDatabaseConnection(t *testing.T) {
    dbCon := &DbConn{}
    _, err := dbCon.Connect()
    if err != nil {
        t.Errorf("test failed. \n %d", err)
    }
}

func TestDatabaseConnectionFail(t *testing.T) {
    var dm dbMock
    dbCon := NewDbConn(dm)
    _, err := dbCon.Connect()
    if err == nil {
        t.Errorf("test failed. %d", err)
    }
}

As you can see, this is a simple database connection logic which I test and mock using an interface. I want to cover 100% of the code, so I have to mock certain methods. The code above, although it works, the second test fails, probably because I'm missing something in my attempts to mock it. Please help..

Aucun commentaire:

Enregistrer un commentaire