根據astaxie大神的意見,在beego上對controller作單測比較困難,他的建議就是把全部邏輯都拆分出來,放到model中。而後對model中的public函數進行測試。git
可是這就會多不少封裝,並且,有些時候對controller的測試多是繞不開的。github
其實對controller進行單測也不是那麼麻煩,重點就是把http須要的Request
和ResponseWriter
須要的數據都構造出來便可。json
下面是個人作法?重點看代碼和註釋吧。不少代碼是self-explanation瀏覽器
package test import ( "github.com/astaxie/beego" "github.com/astaxie/beego/context" "github.com/astaxie/beego/session" "net/http" "net/url" "reflect" "testing" "youApp/controllers" ) func prepareController(c *beego.Controller) { c.Ctx = &context.Context{ Request: &http.Request{URL: &url.URL{Scheme: "http", Host: "localhost", Path: "/"}}, ResponseWriter: &fakeResponseWriter{}, } c.Ctx.Output = &context.BeegoOutput{Context: c.Ctx} c.Ctx.Input = &context.BeegoInput{Request: c.Ctx.Request} globalSessions, _ := session.NewManager("memory", `{"cookieName":"gosessionid","gclifetime":10}`) c.Ctx.Request.Header = http.Header{} c.Ctx.Request.AddCookie(&http.Cookie{Name: "gosessionid", Value: "test"}) c.CruSession = globalSessions.SessionRegenerateId(c.Ctx.ResponseWriter, c.Ctx.Request) c.Data = map[interface{}]interface{}{} } func TestRecomputeBanlance(t *testing.T) { c := &controllers.BanlanceController{} prepareController(&(c.Controller)) // 這是指望用戶在瀏覽器上傳的form表和登錄信息。 c.Ctx.Request.Form = url.Values{ "range": []string{"2016-10-01到2016-10-31"}, "city": []string{"北京"}, } c.SetSession("login", "123") c.Prepare() // 這是對應的控制器函數 c.Recompute() // 本例中,數據是經過json傳出來的。 j := c.Data["json"] // 從json中讀取的數據是interface{}類型,須要經過reflect獲取其中的信息 mapV := reflect.ValueOf(j) errV := mapV.MapIndex(reflect.ValueOf("Error")) // 先看看json中有沒有error字段 if errV.IsValid() && errV.String() != "" { t.Fatal("has error:", errV) } // 而後讀取ban字段的內容 banV := mapV.MapIndex(reflect.ValueOf("ban")) if !banV.IsValid() { t.Fatal("no output data!") } else { V := reflect.ValueOf(banV.Interface()) fnum := V.NumField() if fnum < 10 { t.Fatal("not ban table format") } // 讀取關鍵字段的值進一步判斷 v1 := V.FieldByName("Value1").Float() v2 := V.FieldByName("Value2").Float() v3 := V.FieldByName("Value3").Float() v4 := V.FieldByName("Value4").Float() if !(v1 > 0 && v2 > 0 && v3 > 0 && v4 > 0) { t.Fatal("ban table data wrong:", v1, v2, v3, v4) } } } type fakeResponseWriter struct{} func (f *fakeResponseWriter) Header() http.Header { return http.Header{} } func (f *fakeResponseWriter) Write(b []byte) (int, error) { return 0, nil } func (f *fakeResponseWriter) WriteHeader(n int) {}