Golang中如何通过设置响应cookie来模拟http.Client.Do

Golang中如何通过设置响应cookie来模拟http.Client.Do 我有一个方法,其签名如下:

func Login(client pkg.HTTPClient, userName, password string) ([]*http.Cookie, error) {}

这里的 pkg.HTTPClient 是一个接口,定义如下:

package pkg

type HTTPClient interface {
    Do(req *http.Request) (*http.Response, error)
}

我的目的是模拟 client.Do 方法,并在 client.Do 的响应中设置 Cookie。

我不确定如何实现这一点,因为当我检查 http.Response 对象时,没有找到设置 Cookie 的方法。


更多关于Golang中如何通过设置响应cookie来模拟http.Client.Do的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

假设你在模拟中创建了一个 *ResponseRecorder,例如 recorder := httptest.NewRecorder(),可以使用 http.SetCookie(recorder, &http.Cookie{Name: "test", Value: "expected"}) 来设置 cookie。

更多关于Golang中如何通过设置响应cookie来模拟http.Client.Do的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang中,可以通过创建自定义的HTTP客户端实现来模拟响应中的Cookie设置。以下是具体实现示例:

package main

import (
    "net/http"
    "net/http/httptest"
    "net/url"
)

// 模拟HTTP客户端实现
type mockHTTPClient struct {
    cookies []*http.Cookie
}

func (m *mockHTTPClient) Do(req *http.Request) (*http.Response, error) {
    // 创建测试响应记录器
    recorder := httptest.NewRecorder()
    
    // 设置响应Cookie
    for _, cookie := range m.cookies {
        http.SetCookie(recorder, cookie)
    }
    
    // 设置响应状态码和头部
    recorder.WriteHeader(http.StatusOK)
    
    // 返回响应
    return recorder.Result(), nil
}

// 使用示例
func main() {
    // 创建模拟客户端并设置Cookie
    mockClient := &mockHTTPClient{
        cookies: []*http.Cookie{
            {
                Name:  "session_id",
                Value: "abc123",
                Path:  "/",
            },
            {
                Name:  "user_token",
                Value: "xyz789",
                Path:  "/",
            },
        },
    }
    
    // 创建请求
    req, _ := http.NewRequest("GET", "http://example.com/login", nil)
    
    // 执行请求
    resp, err := mockClient.Do(req)
    if err != nil {
        panic(err)
    }
    
    // 验证响应中的Cookie
    cookies := resp.Cookies()
    for _, cookie := range cookies {
        println("Cookie:", cookie.Name, "=", cookie.Value)
    }
}

如果需要更灵活的模拟,可以使用httptest.NewServer:

package main

import (
    "net/http"
    "net/http/httptest"
    "net/url"
)

func Login(client HTTPClient, userName, password string) ([]*http.Cookie, error) {
    // 创建登录请求
    form := url.Values{}
    form.Add("username", userName)
    form.Add("password", password)
    
    req, _ := http.NewRequest("POST", "http://example.com/login", 
        strings.NewReader(form.Encode()))
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    
    // 执行请求
    resp, err := client.Do(req)
    if err != nil {
        return nil, err
    }
    
    // 返回Cookie
    return resp.Cookies(), nil
}

// 测试示例
func TestLogin(t *testing.T) {
    // 创建测试服务器
    server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 设置响应Cookie
        http.SetCookie(w, &http.Cookie{
            Name:  "session_token",
            Value: "test_session_123",
            Path:  "/",
        })
        http.SetCookie(w, &http.Cookie{
            Name:  "user_id",
            Value: "456",
            Path:  "/",
        })
        
        w.WriteHeader(http.StatusOK)
    }))
    defer server.Close()
    
    // 创建HTTP客户端
    client := server.Client()
    
    // 调用Login函数
    cookies, err := Login(client, "testuser", "password123")
    if err != nil {
        t.Fatal(err)
    }
    
    // 验证返回的Cookie
    if len(cookies) != 2 {
        t.Errorf("Expected 2 cookies, got %d", len(cookies))
    }
}

对于单元测试场景,可以直接实现HTTPClient接口:

package pkg

import (
    "net/http"
)

type mockClient struct {
    response *http.Response
    err      error
}

func (m *mockClient) Do(req *http.Request) (*http.Response, error) {
    return m.response, m.err
}

// 测试用例
func TestLoginWithMock(t *testing.T) {
    // 创建模拟响应
    resp := &http.Response{
        StatusCode: http.StatusOK,
        Header:     make(http.Header),
    }
    
    // 通过Header设置Cookie
    resp.Header.Add("Set-Cookie", "session_id=abc123; Path=/")
    resp.Header.Add("Set-Cookie", "user_token=def456; Path=/")
    
    // 创建模拟客户端
    mockClient := &mockClient{
        response: resp,
        err:      nil,
    }
    
    // 测试Login函数
    cookies, err := Login(mockClient, "user", "pass")
    if err != nil {
        t.Fatal(err)
    }
    
    // 验证结果
    if len(cookies) != 2 {
        t.Errorf("Expected 2 cookies, got %d", len(cookies))
    }
}

这些示例展示了如何在Golang中通过不同方式模拟HTTP客户端并在响应中设置Cookie。

回到顶部