これは、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)
}
これを手動で試してみると、すべてうまくいきます。
ただし、これを単体テストに合格させることはできないようです。対応するテスト ファイルでは、これは my を読み込もうとするテスト コード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 から何も取得されない状況を考慮し、アサーションを適用してそれを検証し、検証済みのテストを作成します。