Golang中如何模拟请求(Mocking requests)

Golang中如何模拟请求(Mocking requests) 分享一篇由Zus技术专家Sonya Huang撰写的关于在Go中模拟请求的有趣文章:

linkedin.com

Zus Health on LinkedIn: mocking outbound http requests in go: you’re…

文章图片

引用Harry和Lloyd的不朽名言:

Mock Yeah Ing Yeah Outbound http request in go Yeah Yeah Yeah Mocking (outbound http request in go) now

一篇新的…


更多关于Golang中如何模拟请求(Mocking requests)的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中如何模拟请求(Mocking requests)的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go中模拟HTTP请求通常使用net/http/httptest包创建测试服务器,或通过接口抽象配合依赖注入。以下是两种常见方法:

1. 使用httptest.Server模拟外部API

package main

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

func main() {
    // 创建测试服务器
    server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(http.StatusOK)
        w.Header().Set("Content-Type", "application/json")
        io.WriteString(w, `{"status": "ok"}`)
    }))
    defer server.Close()

    // 使用测试服务器的URL
    resp, err := http.Get(server.URL)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, _ := io.ReadAll(resp.Body)
    fmt.Printf("Response: %s", body)
}

2. 通过接口抽象实现模拟

package main

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

// 定义HTTP客户端接口
type HTTPClient interface {
    Do(req *http.Request) (*http.Response, error)
}

// 实际实现
type RealClient struct {
    client *http.Client
}

func (c *RealClient) Do(req *http.Request) (*http.Response, error) {
    return c.client.Do(req)
}

// 模拟实现
type MockClient struct{}

func (c *MockClient) Do(req *http.Request) (*http.Response, error) {
    // 返回模拟响应
    return &http.Response{
        StatusCode: http.StatusOK,
        Body:       io.NopCloser(io.Reader(io.MultiReader())),
    }, nil
}

// 业务逻辑使用接口
type Service struct {
    client HTTPClient
}

func (s *Service) MakeRequest() {
    req, _ := http.NewRequest("GET", "https://api.example.com", nil)
    resp, _ := s.client.Do(req)
    fmt.Printf("Status: %d", resp.StatusCode)
}

func main() {
    // 测试时使用模拟客户端
    service := &Service{client: &MockClient{}}
    service.MakeRequest()
}

3. 使用gock库进行HTTP模拟

package main

import (
    "fmt"
    "net/http"
    "gopkg.in/h2non/gock.v1"
)

func main() {
    defer gock.Off()

    // 模拟请求
    gock.New("https://api.example.com").
        Get("/users").
        Reply(200).
        JSON(map[string]string{"name": "John"})

    // 执行请求
    resp, err := http.Get("https://api.example.com/users")
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    fmt.Printf("Status: %d", resp.StatusCode)
}

这些方法允许在测试中隔离外部依赖,确保测试的可靠性和执行速度。httptest适合简单场景,接口抽象提供更好的灵活性,而gock库适合复杂的HTTP交互模拟。

回到顶部