Kaynağa Gözat

add selftest unit

zjxpcyc 6 yıl önce
ebeveyn
işleme
96d7f5bad1
3 değiştirilmiş dosya ile 295 ekleme ve 0 silme
  1. 54
    0
      tests/cases_test.go
  2. 29
    0
      tests/tests.go
  3. 212
    0
      tests/utils.go

+ 54
- 0
tests/cases_test.go Dosyayı Görüntüle

@@ -0,0 +1,54 @@
1
+package tests
2
+
3
+import (
4
+	"net/http"
5
+	"net/url"
6
+	"spaceofcheng/services/controllers"
7
+	"testing"
8
+
9
+	. "github.com/smartystreets/goconvey/convey"
10
+)
11
+
12
+func TestGetCmsCaseList(t *testing.T) {
13
+
14
+	Convey("获取案场列表", t, func() {
15
+
16
+		Convey("正常业务", func() {
17
+			params := url.Values{}
18
+			params.Add("orgid", "1")
19
+
20
+			result := &controllers.JSONMessage{}
21
+
22
+			code, _, err := NewRequestMock().Request(http.MethodGet, "/api/guest/MQ/cms/case", params, result)
23
+
24
+			// http 常规判断, 可以省略
25
+			So(code, ShouldEqual, http.StatusOK)
26
+			So(err, ShouldBeNil)
27
+
28
+			// 业务返回判断
29
+			Convey("结果码 200", func() {
30
+				So(result.Code, ShouldEqual, http.StatusOK)
31
+			})
32
+
33
+			Convey("结果不为空", func() {
34
+				So(result.Result, ShouldNotBeEmpty)
35
+			})
36
+		})
37
+
38
+		Convey("机构不传报错", func() {
39
+			result := &controllers.JSONMessage{}
40
+
41
+			code, _, err := NewRequestMock().Request(http.MethodGet, "/api/guest/MQ/cms/case", nil, result)
42
+
43
+			// http 常规判断, 可以省略
44
+			So(code, ShouldEqual, http.StatusOK)
45
+			So(err, ShouldBeNil)
46
+
47
+			// 业务返回判断
48
+			Convey("结果码 不是200", func() {
49
+				So(result.Code, ShouldNotEqual, http.StatusOK)
50
+			})
51
+		})
52
+
53
+	})
54
+}

+ 29
- 0
tests/tests.go Dosyayı Görüntüle

@@ -0,0 +1,29 @@
1
+package tests
2
+
3
+/**
4
+*
5
+* 使用的测试框架为  http://labix.org/gocheck
6
+*
7
+**/
8
+
9
+import (
10
+	"spaceofcheng/services/bootstrap"
11
+	"spaceofcheng/services/utils"
12
+	"testing"
13
+
14
+	_ "spaceofcheng/services/routers"
15
+
16
+	"github.com/astaxie/beego"
17
+	. "github.com/smartystreets/goconvey/convey"
18
+)
19
+
20
+func TestHelloWorld(t *testing.T) {
21
+	Convey("Hello go tester !", t, func() {
22
+		So(2, ShouldEqual, 2)
23
+	})
24
+}
25
+
26
+func init() {
27
+	bootstrap.SystemInit()
28
+	beego.TestBeegoInit(utils.GetAppRoot())
29
+}

+ 212
- 0
tests/utils.go Dosyayı Görüntüle

@@ -0,0 +1,212 @@
1
+package tests
2
+
3
+import (
4
+	"bytes"
5
+	"encoding/json"
6
+	"errors"
7
+	"fmt"
8
+	"io"
9
+	"io/ioutil"
10
+	"mime/multipart"
11
+	"net/http"
12
+	"net/http/httptest"
13
+	"net/url"
14
+	"os"
15
+	"strconv"
16
+	"strings"
17
+	"time"
18
+
19
+	"github.com/astaxie/beego"
20
+)
21
+
22
+// RequestMock 模拟请求
23
+type RequestMock struct {
24
+	Headers map[string]string
25
+	Host    string
26
+}
27
+
28
+// NewRequestMock new inst
29
+func NewRequestMock() *RequestMock {
30
+	return &RequestMock{
31
+		Headers: make(map[string]string),
32
+	}
33
+}
34
+
35
+// SetHeaders 设置自定义请求头
36
+func (t *RequestMock) SetHeaders(headers map[string]string) *RequestMock {
37
+	t.Headers = headers
38
+	return t
39
+}
40
+
41
+// SetHost 设置 host 包含 port
42
+func (t *RequestMock) SetHost(host string) *RequestMock {
43
+	t.Host = host
44
+	return t
45
+}
46
+
47
+// Request 请求
48
+// 暂时只支持 params 是 url.Values 及 map[string]interface{} 两种类型
49
+// url.Values 将被理解为 content-type="application/x-www-form-urlencoded"
50
+// map[string]interface{} 将被理解为 content-type="multipart/form-data"
51
+func (t *RequestMock) Request(meth, addr string, params interface{}, result interface{}) (code int, body []byte, err error) {
52
+	var r *http.Request
53
+	defer t.SetHeaders(nil)
54
+
55
+	code = 0
56
+	body = nil
57
+	err = nil
58
+
59
+	if t.Host != "" {
60
+		addr = t.Host + addr
61
+	} else {
62
+		addr = "http://127.0.0.1:8080" + addr
63
+	}
64
+
65
+	switch meth {
66
+
67
+	// get 请求, 只支持 params 为 url.Values 的参数
68
+	case http.MethodGet:
69
+		if params != nil {
70
+			if dt, ok := params.(url.Values); ok {
71
+				searchStr := dt.Encode()
72
+				if strings.Index(addr, "?") > -1 {
73
+					searchStr = "&" + searchStr
74
+				} else {
75
+					searchStr = "?" + searchStr
76
+				}
77
+				r, _ = http.NewRequest(meth, addr+searchStr, nil)
78
+			}
79
+		} else {
80
+			r, _ = http.NewRequest(meth, addr, nil)
81
+		}
82
+
83
+	// post, put, delete
84
+	case http.MethodPost, http.MethodPut, http.MethodDelete:
85
+		rb, ct, e := GetBody(params)
86
+		if e != nil {
87
+			err = e
88
+			return
89
+		}
90
+
91
+		r, _ = http.NewRequest(meth, addr, rb)
92
+		if ct != "" {
93
+			r.Header.Set("Content-Type", ct)
94
+		}
95
+
96
+	// 其他的本系统没有使用
97
+	default:
98
+		err = errors.New("不支持的请求类型")
99
+		return
100
+	}
101
+
102
+	// 自定义的 header 头
103
+	if t.Headers != nil {
104
+		for k, v := range t.Headers {
105
+			r.Header.Set(k, v)
106
+		}
107
+	}
108
+
109
+	w := httptest.NewRecorder()
110
+	beego.BeeApp.Handlers.ServeHTTP(w, r)
111
+
112
+	code = w.Code
113
+	body, _ = ioutil.ReadAll(w.Result().Body)
114
+
115
+	beego.Trace("testing", meth+" - "+addr)
116
+
117
+	if result != nil {
118
+		err = json.Unmarshal(body, result)
119
+		return
120
+	}
121
+
122
+	return
123
+}
124
+
125
+func GetBody(params interface{}) (body io.Reader, contentType string, err error) {
126
+	body = nil
127
+	contentType = ""
128
+	err = nil
129
+
130
+	if params == nil {
131
+		return
132
+	}
133
+
134
+	t := fmt.Sprintf("%T", params)
135
+	switch t {
136
+
137
+	// 被会解析为 application/x-www-form-urlencoded
138
+	case "url.Values":
139
+		data, _ := params.(url.Values)
140
+		body = strings.NewReader(data.Encode())
141
+		contentType = "application/x-www-form-urlencoded"
142
+		return
143
+
144
+	// 被会解析为 multipart/form-data
145
+	case "map[string]interface {}":
146
+		var b bytes.Buffer
147
+		var fw io.Writer
148
+
149
+		w := multipart.NewWriter(&b)
150
+		data, _ := params.(map[string]interface{})
151
+
152
+		// 遍历字段
153
+		for k, v := range data {
154
+			switch x := v.(type) {
155
+
156
+			// 文件
157
+			case *os.File:
158
+				if fw, err = w.CreateFormFile(k, x.Name()); err != nil {
159
+					return
160
+				}
161
+
162
+				if _, err = io.Copy(fw, x); err != nil {
163
+					return
164
+				}
165
+
166
+			// 字符串
167
+			case string:
168
+				err = w.WriteField(k, x)
169
+				if err != nil {
170
+					return
171
+				}
172
+
173
+			// 整数, 暂不支持 int 各种原始类型, 比如 int32, int64 等
174
+			case int:
175
+				dt := strconv.Itoa(x)
176
+				err = w.WriteField(k, dt)
177
+				if err != nil {
178
+					return
179
+				}
180
+
181
+			// 小数, 暂时不支持其他类型的浮点数
182
+			case float64:
183
+				dt := strconv.FormatFloat(x, 'f', -1, 64)
184
+				err = w.WriteField(k, dt)
185
+				if err != nil {
186
+					return
187
+				}
188
+
189
+			// 时间
190
+			case time.Time:
191
+				dt := x.Format("2006-01-02 15:04:05")
192
+				err = w.WriteField(k, dt)
193
+				if err != nil {
194
+					return
195
+				}
196
+
197
+			// 其他
198
+			default:
199
+				err = fmt.Errorf("暂时不支持 key "+k+" 对应的数据类型 %T", x)
200
+				return
201
+			}
202
+		}
203
+
204
+		body = bytes.NewReader(b.Bytes())
205
+		contentType = w.FormDataContentType()
206
+		return
207
+
208
+	default:
209
+		err = fmt.Errorf("暂时不支持的参数类型 " + t)
210
+		return
211
+	}
212
+}