英文:
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())
}
}
我觉得这是一个非常基本的测试用例,我只是检查响应的长度(这是因为我期望得到一个切片)。我不确定这是否是编写测试用例的正确方式。请指出一些漏洞,以便我可以为我的其他处理程序编写稳固的测试用例。另外,我没有使用实际的Error
和Fatal
方法来检查错误。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论