-
Notifications
You must be signed in to change notification settings - Fork 3
/
gin.go
132 lines (116 loc) · 2.85 KB
/
gin.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package testutils
import (
"encoding/json"
"errors"
"gatecloud-boilerplate/api/validations"
"net/http"
"net/http/httptest"
"reflect"
"github.com/gin-gonic/gin"
"github.com/go-redis/redis"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
)
type Mocker interface {
MockRESTfulAPI() error
}
type TestConfig struct {
DbDrive string
DbConnection string
Controller reflect.Type
Model interface{}
Action string
Actual interface{}
URL string
Body interface{}
}
func (config *TestConfig) MockRESTfulAPI() (int, error) {
var (
statusCode int
err error
)
ptr := reflect.New(config.Controller)
// Init Controller
methodInit := ptr.MethodByName("Init")
if !methodInit.IsValid() {
return http.StatusInternalServerError, errors.New("init error")
}
db, err := initMockDB(config.DbDrive, config.DbConnection)
if err != nil {
return http.StatusInternalServerError, err
}
validator := validations.InitValidation()
redis := &redis.Client{}
args := make([]reflect.Value, 4)
args[0] = reflect.ValueOf(db)
args[1] = reflect.ValueOf(validator)
args[2] = reflect.ValueOf(redis)
args[3] = reflect.ValueOf(config.Model)
methodInit.Call(args)
// Create mock HTTP server
resp := httptest.NewRecorder()
ctx, router := gin.CreateTestContext(resp)
gin.SetMode(gin.ReleaseMode)
relativePath, method := parseAction(config.Action)
router.Handle(method, relativePath, func(c *gin.Context) {
m := ptr.MethodByName(config.Action)
if !m.IsValid() {
statusCode = http.StatusMethodNotAllowed
err = errors.New("action not found")
return
}
args := make([]reflect.Value, 1)
args[0] = reflect.ValueOf(c)
m.Call(args)
if resp.Body.Len() == 0 {
statusCode = http.StatusNoContent
err = nil
return
}
err = json.Unmarshal(resp.Body.Bytes(), config.Actual)
})
if err != nil {
return statusCode, err
}
ctx.Request, err = http.NewRequest(http.MethodGet, config.URL, nil)
if err != nil {
return http.StatusInternalServerError, err
}
router.ServeHTTP(resp, ctx.Request)
if statusCode == http.StatusNoContent {
return statusCode, err
}
return http.StatusOK, nil
}
// initMockDB connects the specific database and returns the handler
func initMockDB(drive, conn string) (*gorm.DB, error) {
db, err := gorm.Open(drive, conn)
if err != nil {
return nil, err
}
db.LogMode(false)
return db, nil
}
func parseAction(action string) (relativePath string, method string) {
switch action {
case "GetByID":
relativePath = "/test/:id"
method = http.MethodGet
case "GetAll":
relativePath = "/test"
method = http.MethodGet
case "Post":
relativePath = "/test"
method = http.MethodPost
case "Patch":
relativePath = "/test"
method = http.MethodPatch
case "Delete":
relativePath = "/test"
method = http.MethodDelete
default:
relativePath = ""
method = ""
}
return
}