我完全不知道如何模拟一个函数,而不使用任何额外的包,如 golang/mock。我只是想学习如何做到这一点,但找不到很多像样的在线资源。
本质上,我关注了这篇优秀的文章,该文章解释了如何使用接口来模拟事物。
因此,我重新编写了我想测试的功能。该函数只是将一些数据插入数据存储区。我的测试没问题——我可以直接模拟这个函数。
我遇到的问题是在我试图测试的 http 路由中模拟它。我正在使用 Gin 框架。
我的路由器(简化版)如下所示:
func SetupRouter() *gin.Engine {
r := gin.Default()
r.Use(gin.Logger())
r.Use(gin.Recovery())
v1 := r.Group("v1")
v1.PATCH("operations/:id", controllers.UpdateOperation)
}
调用 UpdateOperation 函数:
func UpdateOperation(c *gin.Context) {
id := c.Param("id")
r := m.Response{}
str := m.OperationInfoer{}
err := m.FindAndCompleteOperation(str, id, r.Report)
if err == nil {
c.JSON(200, gin.H{
"message": "Operation completed",
})
}
}
所以,我需要模拟 FindAndCompleteOperation() 函数。
主要(简化)函数如下所示:
func (oi OperationInfoer) FindAndCompleteOp(id string, report Report) error {
ctx := context.Background()
q := datastore.NewQuery("Operation").
Filter("Unique_Id =", id).
Limit(1)
var ops []Operation
if ts, err := db.Datastore.GetAll(ctx, q, &ops); err == nil {
{
if len(ops) > 0 {
ops[0].Id = ts[0].ID()
ops[0].Complete = true
// Do stuff
_, err := db.Datastore.Put(ctx, key, &o)
if err == nil {
log.Print("OPERATION COMPLETED")
}
}
}
}
err := errors.New("Not found")
return err
}
func FindAndCompleteOperation(ri OperationInfoer, id string, report Report) error {
return ri.FindAndCompleteOp(id, report)
}
type OperationInfoer struct{}
为了测试更新操作的路线,我有这样的事情:
FIt("Return 200, updates operation", func() {
testRouter := SetupRouter()
param := make(url.Values)
param["access_token"] = []string{public_token}
report := m.Report{}
report.Success = true
report.Output = "my output"
jsonStr, _ := json.Marshal(report)
req, _ := http.NewRequest("PATCH", "/v1/operations/123?"+param.Encode(), bytes.NewBuffer(jsonStr))
resp := httptest.NewRecorder()
testRouter.ServeHTTP(resp, req)
Expect(resp.Code).To(Equal(200))
o := FakeResponse{}
json.NewDecoder(resp.Body).Decode(&o)
Expect(o.Message).To(Equal("Operation completed"))
})
最初,我试图作弊,只是尝试了这样的事情:
m.FindAndCompleteOperation = func(string, m.Report) error {
return nil
}
但这会影响所有其他测试等。
我希望有人可以简单地解释模拟 FindAndCompleteOperation 函数的最佳方法是什么,这样我就可以测试路线,而不依赖于数据存储等。