根据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) {}