You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建Write时返回错误的http.ResponseWriter模拟实例用于Go测试

模拟Write失败的HTTP响应写入器实现

要测试json.Marshal失败同时responseWriter.Write也失败的场景,你需要自定义一个实现http.ResponseWriter接口的结构体,手动让它的Write方法返回错误——毕竟httptest.NewRecorder()的Write方法永远不会返回错误。具体实现步骤如下:

1. 定义Mock响应写入器结构体

这个结构体要实现http.ResponseWriter的所有必要方法,我们只需要在Write方法中返回预设的错误即可:

import (
    "http"
    "io"
    "strconv"
)

type MockFailedResponseWriter struct {
    header   http.Header
    writeErr error // 预设的Write方法返回错误
}

// 创建Mock实例的构造函数
func NewMockFailedResponseWriter(err error) *MockFailedResponseWriter {
    return &MockFailedResponseWriter{
        header:   make(http.Header),
        writeErr: err,
    }
}

// 实现http.ResponseWriter的Header方法
func (m *MockFailedResponseWriter) Header() http.Header {
    return m.header
}

// 实现http.ResponseWriter的WriteHeader方法
func (m *MockFailedResponseWriter) WriteHeader(statusCode int) {
    // 可以记录状态码,方便后续测试验证
    m.header.Set("X-Recorded-Status", strconv.Itoa(statusCode))
}

// 实现http.ResponseWriter的Write方法,强制返回预设错误
func (m *MockFailedResponseWriter) Write([]byte) (int, error) {
    return 0, m.writeErr
}

2. 在测试中使用Mock实例

构造无法序列化的测试数据,传入自定义的Mock写入器,验证WriteResponse函数的错误处理逻辑:

func TestWriteResponse_DoubleFailure(t *testing.T) {
    // 构造一个无法被json.Marshal序列化的对象(循环引用)
    type Circular struct {
        Self *Circular
    }
    invalidData := Circular{}
    invalidData.Self = &invalidData

    // 创建模拟Write失败的实例,用标准库错误模拟真实场景
    mockWriter := NewMockFailedResponseWriter(io.ErrClosedPipe)

    // 调用你的WriteResponse函数
    err := WriteResponse(mockWriter, http.StatusOK, invalidData)

    // 验证错误是否符合预期
    if err == nil {
        t.Fatal("expected error when both marshal and write failed, got nil")
    }
    // 可额外验证错误场景下的状态码、Header是否正确设置
    if mockWriter.Header().Get("X-Recorded-Status") != "500" {
        t.Errorf("expected status code 500, got %s", mockWriter.Header().Get("X-Recorded-Status"))
    }
}

3. 补充说明

  • http.ResponseWriter接口要求必须实现Header()、Write([]byte)、WriteHeader(int)三个方法,自定义结构体必须全部覆盖。
  • 你可以根据测试需求调整WriteHeader的逻辑,比如记录状态码用于后续验证;预设的错误也可以换成io.EOF等其他标准错误,或者自定义业务错误。

内容的提问来源于stack exchange,提问作者baitendbidz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 18:13:24