samedi 2 mai 2020

Go Test Failing in Database Exec Connected to PostgreSQL

Just started with building a Go API application. I am having some issues with the DB Exec command being run in the test file (main_test.go) with the error:

runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference

Below are my source codes

App.go

package main

import (
    "database/sql"
    "fmt"
    "log"
    "net/http"
    "encoding/json"
    "strconv"

    "github.com/gorilla/mux"
    _ "github.com/lib/pq"
)

const (
  host     = "localhost"
  port     = 5432
  user     = "user"
  password = "password"
  dbname   = "mydb"
)

type App struct {
    Router *mux.Router
    DB *sql.DB
}

func (a *App) Initialize () {
    println("Initialize in App.go....")
    connectionString := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
        host, port, user, password, dbname)
    var err error
    a.DB, err = sql.Open("postgres", connectionString)
    if err != nil {
        log.Print("ERROR CONNECTING TO DB...")
        log.Fatal(err)
    }

    a.Router = mux.NewRouter()
    a.initializeRoutes()
}

func (a *App) Run (addr string) {
    log.Fatal(http.ListenAndServe(":8010", a.Router))
}

...... (codes below are the api methods (GET, POST, etc.) omitted for brevity.)

And here is my main.go

// main.go
package main

func main() {
    a := App{}
    a.Initialize()
    a.Run(":8010")

}

And my test, main_test.go

package main

import (
    "os"
    "testing"
    "log"
    "net/http"
    "net/http/httptest"
    "strconv"
    "encoding/json"
    "bytes"
)

var a App

func MainTest(m *testing.M) {
    a.Initialize()

    ensureTableExists()

    code := m.Run()

    clearTable()

    os.Exit(code)
}

func ensureTableExists() {
    if _, err := a.DB.Exec(tableCreationQuery); err != nil {
        log.Fatal(err)
    }
}

const tableCreationQuery = `Query to Create a Database Table`

func clearTable() {
    println("clearTable Running...")
    a.DB.Exec("DELETE FROM table_name")
    a.DB.Exec("ALTER SEQUENCE table_name_id_seq RESTART WITH 1")
}

func TestEmptyTable(t *testing.T) {
    clearTable()

    req, _ := http.NewRequest("GET", "/api/patient", nil)
    response := executeRequest(req)

    checkResponseCode(t, http.StatusOK, response.Code)

    if body := response.Body.String(); body != "[]" {
        t.Errorf("Expected empty array. Got %s", body)
    } 
}

..... (other tests below, but ommitted for brevity. error happens on the code above)

}

Before I forget, I also have a model.go file:

package main

import (
    "database/sql"
    "time"
)

type table_name struct {
    Id  int     `json:"id"`
    Col1    string      `json:"col1"`
    Col2    string      `json:"col2"`
    Col3    string      `json:"col3"`
}

// Codes after this are just my usual query calls to the table_name...
// Ommitted for brevity...

So in my console, the error is happening on the line:

a.DB.Exec("DELETE FROM table_name")

With the following:

--**- FAIL:** TestEmptyTable (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
        panic: runtime error: invalid memory address or nil pointer dereference    
[signal 0xc0000005 code=0x1 addr=0x20 pc=0x544a98]

This is logged when I execute the command in my console:

go test -v

I have no issues when I try to run the application like:

go run .

As I can clearly make the http API calls through Postman (or directly in the browser).

So the main issue I have is on the Test which are failing for reasons I do not have any idea.

I am unsure where to go from here. Help is definitely welcome.

Gracias.

Aucun commentaire:

Enregistrer un commentaire