我们可以把它想成Unit Test单元测试的一种,不过它所涵盖的最好集合不像以往的UnitTest可能以Function
为主,而是Endpoint
。
透过API Test我们能够在开发与修改程序码时,确保被修改到部分程序码的API能够如预期的运作,那这边我们会以官方提供的httptest
来实作。
首先我们将main当中的router部分给分离出来
main.go
package main
import (
"fmt"
"github.com/chenyahui/gin-cache/persist"
"github.com/gin-gonic/gin"
"github.com/go-redis/redis/v8"
"github.com/joho/godotenv"
ginSwagger "github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"
"ironman-2021/app/config"
"ironman-2021/app/dao"
"ironman-2021/app/middleware"
"ironman-2021/app/model"
"net/http"
"os"
)
// @title Gin swagger
// @version 1.0
// @description Gin swagger
// @contact.name Flynn Sun
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host localhost:8080
// schemes http
// @securityDefinitions.apikey BearerAuth
// @in header
// @name Authorization
func main() {
envErr := godotenv.Load()
if envErr != nil {
panic(envErr)
}
port := os.Getenv("PORT")
server := SetRouter()
err := server.Run(":" + port)
if err != nil {
panic(err)
}
}
func SetRouter() *gin.Engine {
envErr := godotenv.Load()
if envErr != nil {
panic(envErr)
}
dbConfig := os.Getenv("DB_CONFIG")
db, ormErr := dao.Initialize(dbConfig)
if ormErr != nil {
panic(ormErr)
}
migrateErr := db.AutoMigrate(&model.User{})
if migrateErr != nil {
return nil
}
server := gin.Default()
server.Use(middleware.CORSMiddleware())
server.GET("/hc", func(c *gin.Context) {
c.String(http.StatusOK, fmt.Sprintf("Health Check"))
})
redisStore := persist.NewRedisStore(redis.NewClient(&redis.Options{
Network: "tcp",
Addr: "redis:6379",
DB: 0,
}))
config.RouteUsers(server, redisStore)
url := ginSwagger.URL("http://localhost:8080/swagger/doc.json")
server.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, url))
return server
}
接着则在专案的根目录加上一个main_test.go
的档案
main_test.go
package main
import (
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"testing"
)
func Test_setupRouter(t *testing.T) {
router := SetRouter()
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/hc", nil)
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
assert.Contains(t, w.Body.String(), "Health Check")
}
ResponseRecorder
的物件/hc
的Response给conform到ResponseRecorder
docker exec -it ironman-2021 bash 4280 16:27:57
root@88c2c60ca49b:/usr/local/go/src/ironman-2021# ls
go test -v
的command执行单元测试go test -v
=== RUN Test_setupRouter
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET /hc --> ironman-2021.SetRouter.func1 (4 handlers)
[GIN-debug] POST /v1/users/ --> ironman-2021/app/controller.UsersController.CreateUser-fm (4 handlers)
[GIN-debug] GET /v1/users/:id --> ironman-2021/app/controller.UsersController.GetUser-fm (6 handlers)
[GIN-debug] POST /v1/users/login --> ironman-2021/app/controller.UsersController.AuthHandler-fm (4 handlers)
[GIN-debug] GET /swagger/*any --> github.com/swaggo/gin-swagger.CustomWrapHandler.func1 (4 handlers)
[GIN] 2021/10/08 - 08:29:40 | 200 | 107.8µs | | GET "/hc"
--- PASS: Test_setupRouter (0.06s)
PASS
ok ironman-2021 0.100s
那从这我们就可以看到他执行单元测试的结果与耗费时间等资料,用以确认是否程序码如预期地运作!
再来我们就可以依序写更多的Test Code,从Create a new user 到 Login with an existing user等
package main
import (
"bytes"
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"testing"
)
func Test_setupRouter(t *testing.T) {
router := SetRouter()
w := httptest.NewRecorder()
req1, _ := http.NewRequest("GET", "/hc", nil)
router.ServeHTTP(w, req1)
assert.Equal(t, http.StatusOK, w.Code)
assert.Contains(t, w.Body.String(), "Health Check")
var jsonStr1 = []byte(`{"account":"account","password":"password", "email":"[email protected]"}`)
req2, _ := http.NewRequest("POST", "/v1/users/", bytes.NewBuffer(jsonStr1))
router.ServeHTTP(w, req2)
assert.Equal(t, http.StatusOK, w.Code)
var jsonStr2 = []byte(`{"account":"account","password":"password"`)
req3, _:= http.NewRequest("POST", "/v1/users/login/", bytes.NewBuffer(jsonStr2))
router.ServeHTTP(w, req3)
assert.Equal(t, http.StatusOK, w.Code)
}
这章节主要介绍如何使用官方的httptest
来写Http Test,希望能降低修改程序码时出错的概率!
相关的程序码一样会放在下方连结。
https://github.com/Neskem/Ironman-2021/tree/Day-25
尽管都是模型,但预测模型目的在於预测未来,所以开发方式也会和描述型模型有所差异。 Initiatio...
To fully understand how loop works, I try to break...
来找设计师一起 side project,前後端 / UIUX 皆可ㄛ。配对单连结: https:...
说明:分支的版本还原 还原前1个版本指令 git reset HEAD^ ^可以决定要还原到哪一版,...
随机森林法是什麽? 讲人话就是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数...