如何使用goconvey对gin+gorm+mysql搭建的后台进行集成测试

发布时间 2023-08-08 17:22:02作者: 西门飘柔

集成测试对于项目的质量和稳定性非常重要。那么如何实现一个基于真实数据库的测试流程呢?首先,我们需要创建一个专门用于测试的数据库。比如,我自己使用的是以"test_"开头的数据库名。

// 创建测试数据库
func SetupForTest() (err error) {
	db, err = gorm.Open(setting.DatabaseSetting.Type, fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local",
		setting.DatabaseSetting.User,
		setting.DatabaseSetting.Password,
		setting.DatabaseSetting.Host,
		"test_"+setting.DatabaseSetting.Name))

	if err != nil {
		log.Fatalf("models.Setup err: %v", err)
		return
	}

	// 设置表名前缀
	gorm.DefaultTableNameHandler = func(db *gorm.DB, defaultTableName string) string {
		return setting.DatabaseSetting.TablePrefix + defaultTableName
	}

	db.SingularTable(true)
	db.Callback().Create().Replace("gorm:update_time_stamp", updateTimeStampForCreateCallback)
	db.Callback().Update().Replace("gorm:update_time_stamp", updateTimeStampForUpdateCallback)
	db.Callback().Delete().Replace("gorm:delete", deleteCallback)
	db.DB().SetMaxIdleConns(10)
	db.DB().SetMaxOpenConns(100)

	// 清空所有表格数据
	if err = truncateAllTables(); err != nil {
		return
	}
	
	return
}

然后,在每次初始化完数据库表之后,我们需要执行truncate操作,以清空表格数据。接着,进行一些必要的初始化数据操作。

接下来,我们可以对相关接口进行测试操作。我们可以使用httptest来实现。以下是一个封装了post请求的代码:

// 发送post请求
func PostBody(uri, token string, content interface{}) (r *app.Response, err error) {
	data, err := json.Marshal(content)
	if err != nil {
		return nil, err
	}

	body := bytes.NewReader(data)
	req := httptest.NewRequest("POST", uri, body)
	req.Header.Set("Token", token)
	req.Header.Set("Content-Type", "application/json")

	// 初始化响应
	w := httptest.NewRecorder()
	// 调用相应handler接口
	router.ServeHTTP(w, req)

	// 校验返回状态码
	if w.Result().StatusCode != http.StatusOK {
		err = errors.New("http status error, code: " + fmt.Sprintf("%d", w.Result().StatusCode))
		return
	}

	r = &app.Response{}
	err = json.Unmarshal(w.Body.Bytes(), r)
	if err != nil {
		return
	}

	if r.Code != 0 {
		err = errors.New(r.Msg)
	}

	return
}

最后,我们可以使用goconvey来进行测试。以下是一个示例:

func TestBackLogin(t *testing.T) {
	// 开始一个新的GoConvey测试
	convey.Convey("Testing back login", t, func() {
		// 构造登录请求体
		body := back_user_service.LoginRequest{
			Name:     "admin",
			Password: "MTIz",
		}

		// 发送登录请求,并获取响应
		r, err := PostBody("/admin/v1/login", "", body)
		convey.So(err, convey.ShouldBeNil)

		// 校验返回的token是否为空
		token := r.Data.(map[string]interface{})["token"]
		convey.So(token, convey.ShouldNotBeNil)

		convey.Convey("Testing back login fail", func() {
			// 构造错误的登录请求体
			body := back_user_service.LoginRequest{
				Name:     "admin",
				Password: "MTIz1",
			}

			// 发送错误的登录请求,期望返回错误
			_, err := PostBody("/admin/v1/login", "", body)
			convey.So(err, convey.ShouldBeError)
		})
	})
}

希望以上整理对您有所帮助。如果还有其他问题,请随时提问。