Beego - Endpoint Testing

2019-07-07 04:07发布

问题:

I am testing http custom endpoint for beego

package test

import (
    "github.com/astaxie/beego"
    . "github.com/smartystreets/goconvey/convey"
    _ "golife-api-cons/routers"
    "net/http"
    "net/http/httptest"
    "path/filepath"
    "runtime"
    "testing"
)

func init() {
    _, file, _, _ := runtime.Caller(1)
    apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".."+string(filepath.Separator))))
    beego.TestBeegoInit(apppath)
}

// TestGet is a sample to run an endpoint test
func TestGet(t *testing.T) {
    r, _ := http.NewRequest("GET", "/my/endpoint/fetches/data", nil)
    w := httptest.NewRecorder()
    beego.BeeApp.Handlers.ServeHTTP(w, r)

    beego.Trace("testing", "TestGet", "Code[%d]\n%s", w.Code, w.Body.String())

    Convey("Subject: Test Station Endpoint\n", t, func() {
        Convey("Status Code Should Be 200", func() {
            So(w.Code, ShouldEqual, 200)
        })
        Convey("The Result Should Not Be Empty", func() {
            So(w.Body.Len(), ShouldBeGreaterThan, 0)
        })
    })
}

When i run using go test -v ,

I get in response dial tcp :0: getsockopt: connection refused

I am using MariaDB running on my local, I have verified using netstat -tulpn that my database is running perfectly fine (I get a valid response if i use postman and my server is running)

One weird observation , after inclusion of line _ "golife-api-cons/routers" i get this error even before test's are ran

My test passes with response 200 OK , but without any data as i get in response the above mentioned error

EDIT

The default path by used by TestBeegoInit function used is /path/to/my/project/test which is not the desired path , so i tried giving the absolute path too , still i am not able to connect DB.

回答1:

You are initializing your app as

apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".."+string(filepath.Separator))))
    beego.TestBeegoInit(apppath)
}

Where file is the caller file.

TestBeegoInit is:

func TestBeegoInit(ap string) {
    os.Setenv("BEEGO_RUNMODE", "test")
    appConfigPath = filepath.Join(ap, "conf", "app.conf")
    os.Chdir(ap)
    initBeforeHTTPRun()
}

hence the location where your tests are looking for configuration is

<this_file>/../conf/app.conf

which basically is the default config file.

Basically you are not able to connect to the database. Perhaps because you are unknowingly connecting to your default database for the tests too. I suspect this is not what you are trying to do.



回答2:

After much trying I came to know that beego initializes its variable called as AppPath in beego/conf.go like -

AppPath, _ = filepath.Abs(filepath.Dir(os.Args[0]))

when you run your tests you run them with go test -v

but as a result the os.Args[0] is the text executable which will be /tmp/path/to/test and not path/to/app/exe

hence as a result it does not find config/app.conf which is in your app path which has db connection details. Responsible line in beego/conf.go -

appConfigPath = filepath.Join(AppPath, "conf", "app.conf")

This all happens in beego's init function when you say

import (
  "github.com/astaxie/beego"
  _ "path/to/routers"
)

Hack for this is -

create a new package / file with init function which looks has -

package common

import (
    "os"
    "strings"
)

func init() {
    cwd := os.Getenv("PWD")
    rootDir := strings.Split(cwd, "tests/")
    os.Args[0] = rootDir[0] // path to you dir
}

here you are changing os.Args[0] and assigning your directory path

make sure you import it before beego so now import will look like

import (
  _ "path/to/common"
  "github.com/astaxie/beego"
  _ "path/to/routers"
)

And finally you connect to DB !



标签: go beego