Golang AppEngine API测试错误 "appengine:NewContext传递了未知的http.Request"

3
我正在使用appengine和golang开发简单的RESTful API。当我使用goapp serve启动服务时,代码可以正常运行。我开始编写单元测试函数来测试API端点,但是在这里遇到了恐慌错误appengine:NewContext传递了一个未知的http.Request。当我运行goapp test时,我得到了这个错误。
看起来由于某种原因,我无法将我创建的请求传递给appengine.NewContext()
下面是代码片段...
body := strings.NewReader("")

request, err := http.NewRequest("GET", "endpoint url", body) //inst.NewRequest("GET", goalUrl, body) //
if err != nil {
    t.Error(err)
}
t.Log(request)

c := appengine.NewContext(request) // ERROR: appengine: NewContext passed an unknown http.Request

我已经创建了一个可以重现错误情况的简单代码库,这里是链接。你能帮我看一下吗?或者说有没有人在appengine上拥有用golang编写的API项目,并且有单元测试函数来测试端点,我很想看一下他们的代码...

这里是我发布的GitLab问题,其中包含了所有的问题细节、示例和详细的错误信息。非常感谢你的帮助。
2个回答

2

对于回复延迟,我很抱歉。我自己正在解决这个问题。

以下是我如何解决go appengine单元测试问题的方法:完整的解决方案代码可以在此 github 仓库分支中找到。

在*_test.go文件中,我使用了以下内容:

  • httptest.NewServer(..) 创建测试服务器的新实例。也用于捕获服务的基本URL,该URL用于准备请求对象。
  • aetest.NewContext() 创建用于测试目的的新上下文
  • http.NewRequest(..) 创建新请求
  • gorilla's context.Set(..) 将键(“Context”)和值(上述步骤中创建的上下文)分配给上述创建的请求
  • httptest.NewRecorder() 新记录器以保存结果
  • http.Handler.ServeHTTP(..) 传递记录和请求。用于进行API请求

对于每个API处理程序代码,我没有直接使用appengine.NewContext创建新上下文,而是使用下面描述的代码。

using the gorilla's context.GetOk(..), check 
    IF the received request object has the key "Context"
    THEN using value of that key as the context
    ELSE derive context using appengine.NewContext(r)

我已将可重复使用的功能封装为一个名为aeunittest的单独库,并在我的代码中使用它。
通过这种设置,我能够运行goapp test来触发单元测试。有关解决方案的完整详细信息,请参见已解决代码
以下是帮助我找到此解决方案的博客文章。非常感谢Mark。 在Google App Engine中使用MUX和高阶函数测试GO HTTP处理程序

1
NewContext 从注册的 flight HTTP 请求 中派生上下文。
由于你正在创建一个对 内部 Appengine 包 未知的新请求,所以它会出现错误。
该包还提供了一个 RegisterTestRequest 函数,但在主要文档中没有提到,因此可能会有所不同。我对此没有经验。

谢谢你,但我在文档中看到一条注释,说“它只应该被aetest包使用”。我相信这可能不是一个风险。还有其他解决方案吗? - srini
你为什么需要调用NewContext开始呢?也许更好的方法是完全分离逻辑中特定于appengine的部分,并使应用程序逻辑独立于appengine特定的状态可测试? - nothingmuch
在Appengine数据存储操作中,例如put、get等,Context是必需的,因此在我的情况下它是必需的。 - srini
我的意思是,您可以将这些API抽象为接口,并提供一个模拟上下文和模拟数据存储引导(或仅提供数据存储引擎,如果您可以隐藏上下文),与appengine包兼容但独立。 - nothingmuch
我不确定该怎么做。刚才,我发布了一个对我有用的解决方案。我相信它与你所说的不同。然而,我也很想学习你的解决方案。 - srini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接