如何创建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
相关产品推荐
相关产品推荐

