测试一个连接到Go中的数据库的处理程序

huangapple go评论82阅读模式
英文:

Testing a handler that connects to db in go

问题

我有一个处理程序,它连接到数据库并检索记录。我为此编写了一个测试用例,如下所示:

main_test.go

package main

import (
  "os"
  "fmt"
  "testing"
  "net/http"
  "net/http/httptest"
)

var a App 

func TestMain(m *testing.M) {
    a = App{}
    a.InitializeDB(fmt.Sprintf("postgres://****:****@localhost/db?sslmode=disable"))
    code := m.Run()
    os.Exit(code)
}


func TestRulesetGet(t *testing.T) {

    req, err := http.NewRequest("GET", "/1/sig/", nil)
    if err != nil {
        t.Fatal(err)
    }
    // We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.
    rr := httptest.NewRecorder()
    handler := http.HandlerFunc(a.Get)
    handler.ServeHTTP(rr, req)

    // Check the response body is what we expect.

    if len(rr.Body.String()) != 0 {
      fmt.Println("Status OK : ", http.StatusOK)
        fmt.Println("handler returned body: got ",
            rr.Body.String())
    }
}

我觉得这是一个非常基本的测试用例,我只是检查响应的长度(这是因为我期望得到一个切片)。我不确定这是否是编写测试用例的正确方式。请指出一些漏洞,以便我可以为我的其他处理程序编写稳固的测试用例。另外,我没有使用实际的ErrorFatal方法来检查错误。

英文:

I have a handler which connects to a db and retrieves the records. I wrote a test case for that and it goes this way:

main_test.go

package main

import (
  "os"
  "fmt"
  "testing"
  "net/http"
  "net/http/httptest"
)

var a App 

func TestMain(m *testing.M) {
    a = App{}
    a.InitializeDB(fmt.Sprintf("postgres://****:****@localhost/db?sslmode=disable"))
    code := m.Run()
    os.Exit(code)
}


func TestRulesetGet(t *testing.T) {

    req, err := http.NewRequest("GET", "/1/sig/", nil)
    if err != nil {
        t.Fatal(err)
    }
    // We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.
    rr := httptest.NewRecorder()
    handler := http.HandlerFunc(a.Get)
    handler.ServeHTTP(rr, req)

    // Check the response body is what we expect.

    if len(rr.Body.String()) != 0 {
      fmt.Println("Status OK : ", http.StatusOK)
        fmt.Println("handler returned body: got ",
            rr.Body.String())
    }
}

I feel like this is a very basic test case where I'm just checking the response length (This is because I expect a slice). I'm not really sure whether this is the right way to write a test case. Please point out some loop holes so that I could write a solid test cases for my remaining handlers. And also, I'm not using the actual Error, and Fatal methods for checking the errors.

答案1

得分: 0

如果它能正常工作,那就不算错,但它并没有进行太多验证,只是验证了响应体不为空,甚至没有验证是否成功。我不确定为什么它会打印出http.StatusOK,这是一个常量,并没有告诉你响应中的状态码是什么。

个人而言,当我进行这种级别的测试时,我至少会检查响应码是否符合预期,响应体是否正确解析(如果是 JSON 或 XML),响应数据是否基本正常等等。对于更复杂的负载,我可能会使用黄金文件测试。对于关键代码,我可能会使用模糊(也称为蒙特卡洛)测试。对于性能关键的代码,我可能会添加基准测试和负载测试。测试代码的方法几乎是无限的。你需要弄清楚你的需求是什么,以及如何满足它们。

英文:

If it works then it's not wrong, but it doesn't validate much, only that the response body is non-empty - not even that it's successful. I'm not sure why it prints out http.StatusOK, which is a constant, and doesn't tell you what the status code in the response was.

Personally when I do this level of test I check, at the very least, that the response code is as expected, the response body unmarshals correctly (if it's JSON or XML), the response data is basically sane, etc. For more complex payloads I might use a golden file test. For critical code I might use a fuzz (aka monte carlo) test. For performance-critical code I'll likely add benchmarks and load tests. There are practically infinite ways to test code. You'll have to figure out what your needs are and how to meet them.

huangapple
  • 本文由 发表于 2017年7月6日 02:37:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/44933674.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定