首页 > 后端开发 > Golang > 正文

Golang:使用 httptest 拦截和模拟 HTTP 响应

王林
发布: 2024-02-09 08:24:33
转载
1133 人浏览过

Golang:使用 httptest 拦截和模拟 HTTP 响应

php小编子墨为大家带来了一篇关于Golang中使用httptest拦截和模拟HTTP响应的文章。在这篇文章中,我们将深入探讨如何使用httptest包来进行HTTP请求的拦截和模拟响应,以便于进行单元测试和功能测试。通过使用httptest,我们可以轻松地模拟各种场景下的HTTP响应,进而测试我们的代码的正确性和鲁棒性。无论是对于初学者还是有经验的开发者来说,掌握这些技巧都是非常有用的。接下来,让我们一起来了解具体的实现方法吧!

问题内容

我研究了可用于 golang 中模拟测试的各种不同工具,但我正在尝试使用 httptest 来完成此任务。特别是,我有一个这样的函数:

type contact struct {
  username string
  number int
}

func getResponse(c contact) string {
  url := fmt.Sprintf("https://mywebsite/%s", c.username)
  req, err := http.NewRequest(http.MethodGet, url, nil)
  // error checking
 
  resp, err := http.DefaultClient.Do(req)
  // error checking
  
  return response
}
登录后复制

我读过的很多文档似乎都需要创建客户端接口或自定义传输。有没有办法在不更改此主代码的情况下模拟测试文件中的响应?我想将我的客户端、响应和所有相关详细信息保留在 getresponse 函数中。我可能有错误的想法,但我正在尝试找到一种方法来拦截 http.defaultclient.do(req) 调用并返回自定义响应,这可能吗?

解决方法

我读过似乎需要创建一个客户端界面

根本不改变这个主要代码

保持代码干净是一个很好的做法,您最终会习惯它,可测试的代码更干净,更干净的代码更可测试,所以不必担心更改您的代码(使用接口),这样它就可以接受模拟对象。

最简单形式的代码可以是这样的:

package main

import (
    "fmt"
    "net/http"
)

type contact struct {
    username string
    number   int
}

type client interface {
    do(req *http.request) (*http.response, error)
}

func main() {
    getresponse(http.defaultclient, contact{})
}

func getresponse(client client, c contact) string {
  url := fmt.sprintf("https://mywebsite/%s", c.username)
  req, _ := http.newrequest(http.methodget, url, nil)
  // error checking

  resp, _ := http.defaultclient.do(req)
  // error checking and response processing

  return response
}
登录后复制

你的测试可以是这样的:

package main

import (
    "net/http"
    "testing"
)

type mockclient struct {
}

// do function will cause mockclient to implement the client interface
func (tc mockclient) do(req *http.request) (*http.response, error) {
    return &http.response{}, nil
}

func testgetresponse(t *testing.t) {
    client := new(mockclient)
    getresponse(client, contact{})
}
登录后复制

但是如果您更喜欢使用 httptest:

package main

import (
    "fmt"
    "io"
    "net/http"
    "net/http/httptest"
)

type contact struct {
    username string
    number   int
}

func main() {
    fmt.Println(getResponse(contact{}))
}

func getResponse(c contact) string {
    // Make a test server
    ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "your response")
    }))

    defer ts.Close()

    // You should still set your base url
    base_url := ts.URL

    url := fmt.Sprintf("%s/%s", base_url, c.username)
    req, _ := http.NewRequest(http.MethodGet, url, nil)

    // Use ts.Client() instead of http.DefaultClient in your tests.
    resp, _ := ts.Client().Do(req)

    // Processing the response
    response, _ := io.ReadAll(resp.Body)
    resp.Body.Close()

    return string(response)
}
登录后复制

以上是Golang:使用 httptest 拦截和模拟 HTTP 响应的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:stackoverflow.com
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!