我的编程空间,编程开发者的网络收藏夹
学习永远不晚

gin 的 Context.Redirect 的单元测试适用于 GET 响应代码,但不适用于 POST 响应代码 (golang)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

gin 的 Context.Redirect 的单元测试适用于 GET 响应代码,但不适用于 POST 响应代码 (golang)

在使用Go语言编写Web应用程序时,我们经常会用到gin框架来处理HTTP请求和响应。在进行单元测试时,我们需要对代码进行覆盖测试,以保证代码的质量和稳定性。然而,针对gin的Context.Redirect方法的单元测试在处理GET请求时非常适用,但在处理POST请求时却不太适用。在本文中,php小编苹果将会详细解释为什么这个问题会出现,并提供一些解决方案来进行POST请求的单元测试。

问题内容

我希望我的服务器将特定端点重定向到另一台服务器。该端点可以是 getted 或 posted。在这两种情况下,http 响应代码都应为 302。如果我在此代码上使用 curl ,它确实在两种情况下都显示响应代码 302,并且 curl -l 正确遵循重定向。哇哦。

但是

我的单元测试使用httptest.newrecorder()来捕获信息,但它仅适用于get,不适用于post。因此,当我知道实际的重定向正在工作时,我需要弄清楚如何让单元测试工作。失败测试显示http响应代码是200而不是302(http.statusfound)。

$ go run foo.go
post code 200
get code 302

这是独立测试。

package main

import (
    "net/http"
    "net/http/httptest"
    "github.com/gin-gonic/gin"
)

func main() {
    gin.setmode(gin.releasemode)
    {
        w := httptest.newrecorder()
        context, _ := gin.createtestcontext(w)
        context.request = httptest.newrequest("post", "http://localhost:23632/foobar", nil)
        context.redirect(http.statusfound, "http://foobar.com")

        print("post code ",w.code,"\n")
    }

    {
        w := httptest.newrecorder()
        context, _ := gin.createtestcontext(w)
        context.request = httptest.newrequest("get", "http://localhost:23632/foobar", nil)
        context.redirect(http.statusfound, "http://foobar.com")

        print("get code ",w.code,"\n")
    }
}

当我在实际应用程序(未显示)上执行 curl post 时,我发现它正在工作:

curl -v -XPOST localhost:23632/foobar
* About to connect() to localhost port 23632 (#0)
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 23632 (#0)
> POST /foobar HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:23632
> Accept: */*
>
< HTTP/1.1 302 Found
< Location: http://foobar.com
< Vary: Origin
< Date: Tue, 23 May 2023 22:38:42 GMT
< Content-Length: 0
<
* Connection #0 to host localhost left intact

解决方法

tl;dr

解决方法是在 context.redirect 之后显式调用 context.writer.writeheadernow

说明

这是使用从 gin.createtestcontext 返回的 gin 上下文的一个极端情况。

对于 get 请求,gin 最终会调用 http.redirect ,它将向响应写入一个简短的 html 正文(类似于 found ),从而导致要写入响应的状态代码。

对于 post 请求,http.redirect 不会写入短 html 正文,并且状态代码没有机会写入响应。

参见http 的实现.重定向。根据源码,如果之前设置了content-type header,那么get请求也会出现同样的问题:

{
    w := httptest.newrecorder()
    context, _ := gin.createtestcontext(w)
    context.request = httptest.newrequest("get", "http://localhost:23632/foobar", nil)
+   context.header("content-type", "text/html")
    context.redirect(http.statusfound, "http://foobar.com")
    print("get code ", w.code, "\n")
  }

解决方法是显式调用 context.writer.writeheadernow

{
    w := httptest.NewRecorder()
    context, _ := gin.CreateTestContext(w)
    context.Request = httptest.NewRequest("POST", "http://localhost:23632/foobar", nil)
    context.Redirect(http.StatusFound, "http://foobar.com")
+   context.Writer.WriteHeaderNow()

    print("POST code ", w.Code, "\n")
  }

gin 本身使用相同的解决方法。请参阅 testcontextrenderredirectwithrelativepath。

真正的服务器应用程序不会遇到同样的问题,因为 (*engine).handlehttprequest 将为我们调用 writeheadernow (请参阅 源代码)。这就是为什么我称其为“极端情况”而不是“错误”。

以上就是gin 的 Context.Redirect 的单元测试适用于 GET 响应代码,但不适用于 POST 响应代码 (golang)的详细内容,更多请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

gin 的 Context.Redirect 的单元测试适用于 GET 响应代码,但不适用于 POST 响应代码 (golang)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

gin 的 Context.Redirect 的单元测试适用于 GET 响应代码,但不适用于 POST 响应代码 (golang)

在使用Go语言编写Web应用程序时,我们经常会用到gin框架来处理HTTP请求和响应。在进行单元测试时,我们需要对代码进行覆盖测试,以保证代码的质量和稳定性。然而,针对gin的Context.Redirect方法的单元测试在处理GET请求时
gin 的 Context.Redirect 的单元测试适用于 GET 响应代码,但不适用于 POST 响应代码 (golang)
2024-02-10

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录