unit-testing - 单元测试 golang 处理程序

标签 unit-testing go mgo

这是我编写的用于从 mongodb 检索文档的处理程序。
如果找到文档,我们将相应地加载和呈现模板。 如果失败,它将重定向到 404。

func EventNextHandler(w http.ResponseWriter, r *http.Request) {

    search := bson.M{"data.start_time": bson.M{"$gte": time.Now()}}
    sort := "data.start_time"
    var result *Event
    err := db.Find(&Event{}, search).Sort(sort).One(&result)
    if err != nil && err != mgo.ErrNotFound {
        panic(err)
    }
    if err == mgo.ErrNotFound {
        fmt.Println("No such object in db. Redirect")
        http.Redirect(w, r, "/404/", http.StatusFound)
        return
    }

    // TODO: 
    // This is the absolute path parsing of template files so tests will pass
    // Code can be better organized
    var eventnext = template.Must(template.ParseFiles(
        path.Join(conf.Config.ProjectRoot, "templates/_base.html"),
        path.Join(conf.Config.ProjectRoot, "templates/event_next.html"),
    ))

    type templateData struct {
        Context *conf.Context
        E *Event
    }

    data := templateData{conf.DefaultContext(conf.Config), result}

    eventnext.Execute(w, data)

}

手动尝试,一切正常。

但是,我似乎无法让它通过我的单元测试。在相应的测试文件中,这是我尝试加载我的 EventNextHandler 的测试代码。

func TestEventNextHandler(t *testing.T) {

    // integration test on http requests to EventNextHandler

    request, _ := http.NewRequest("GET", "/events/next/", nil)
    response := httptest.NewRecorder()

    EventNextHandler(response, request)

    if response.Code != http.StatusOK {
        t.Fatalf("Non-expected status code%v:\n\tbody: %v", "200", response.Code)
    }

}

测试在声明 EventNextHandler(response, request) 的行失败。

在我的错误消息中,它指的是我的处理程序代码中的 err := db.Find(&Event{}, search).Sort(sort).One(&result) 行。

完整的错误信息在这里:-

=== RUN TestEventNextHandler
--- FAIL: TestEventNextHandler (0.00 seconds)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x8 pc=0x113eb8]

goroutine 4 [running]:
testing.func·004()
    /usr/local/go/src/pkg/testing/testing.go:348 +0xcd
hp/db.Cursor(0xc2000c3cf0, 0xc2000fb1c0, 0x252d00)
    /Users/calvin/gopath/src/hp/db/db.go:57 +0x98
hp/db.Find(0xc2000c3cf0, 0xc2000fb1c0, 0x252d00, 0xc2000e55c0, 0x252d00, ...)
    /Users/calvin/gopath/src/hp/db/db.go:61 +0x2f
hp/event.EventNextHandler(0xc2000e5580, 0xc2000a16a0, 0xc2000c5680)
    /Users/calvin/gopath/src/hp/event/controllers.go:106 +0x1da
hp/event.TestEventNextHandler(0xc2000d5240)
    /Users/calvin/gopath/src/hp/event/controllers_test.go:16 +0x107
testing.tRunner(0xc2000d5240, 0x526fe0)
    /usr/local/go/src/pkg/testing/testing.go:353 +0x8a
created by testing.RunTests
    /usr/local/go/src/pkg/testing/testing.go:433 +0x86b

goroutine 1 [chan receive]:
testing.RunTests(0x3bdff0, 0x526fe0, 0x1, 0x1, 0x1, ...)
    /usr/local/go/src/pkg/testing/testing.go:434 +0x88e
testing.Main(0x3bdff0, 0x526fe0, 0x1, 0x1, 0x532580, ...)
    /usr/local/go/src/pkg/testing/testing.go:365 +0x8a
main.main()
    hp/event/_test/_testmain.go:43 +0x9a

编写测试的正确方法是什么?考虑到没有从 mongodb 检索到任何内容的情况,并应用断言来验证这一点,从而编写经过验证的测试。

最佳答案

看来我没有在测试中初始化 db。很像类似于所有其他语言的单元测试框架的“设置”步骤。

我必须确保导入了我的 db 包,然后执行两行代码以连接到数据库并注册索引。

func TestEventNextHandler(t *testing.T) {

    // set up test database

    db.Connect("127.0.0.1", "test_db")
    db.RegisterAllIndexes()

    // integration test on http requests to EventNextHandler

    request, _ := http.NewRequest("GET", "/events/next/", nil)
    response := httptest.NewRecorder()

    EventNextHandler(response, request)

    if response.Code != 302 {
        t.Fatalf("Non-expected status code %v:\n\tbody: %v", "200", response.Code)
    }

}

关于unit-testing - 单元测试 golang 处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19763077/

相关文章:

c++ - 为什么在使用解除引用的指针时 EXPECT_CALL 测试意外通过?

unit-testing - 使用模拟器进行 .NET CF 单元测试 - 测试运行错误

unit-testing - Go:如何为多个包运行测试?

perl - 如何为同一发行版中的多个 Perl 模块设计单元测试?

unit-testing - 在 Go 中模拟接收函数

go - 如何在 bigquery 中创建 DateTime 字段并在 golang 中更新它?

go - 重置 golang 中的错误是不好的做法吗?

go - 如何检索当前机器的地址?

mongodb - 我如何使用 mgo 和 Golang 编写以下 Mongo 聚合查询

go - 即使不再维护,我还能继续使用 mgo 吗?