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

如何测试无效Content-Type请求被Chi中间件拦截返回415?

问题:Chi框架AllowContentType中间件测试未生效,无法返回415状态码

我在使用Chi框架的内置AllowContentType中间件,核心业务代码如下:

package main

import (
    "net/http"

    "github.com/go-chi/chi/v5"
    "github.com/go-chi/chi/v5/middleware"
)

func main() {
    http.ListenAndServe(":3000", GetRouter())
}

func GetRouter() *chi.Mux {
    apiRouter := chi.NewRouter()

    apiRouter.Use(middleware.AllowContentType("application/json"))

    apiRouter.Post("/my-route", func(responseWriter http.ResponseWriter, request *http.Request) {
        responseWriter.WriteHeader(http.StatusCreated)
    })

    return apiRouter
}

为了验证当请求的Content-Type不是application/json时接口返回415状态码,我编写了如下测试代码:

package main

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

func TestGetRouter(testing *testing.T) {
    router := GetRouter()

    responseRecorder := httptest.NewRecorder()

    request, _ := http.NewRequest(http.MethodPost, "/my-route", nil)
    request.Header.Set("Content-Type", "text/xml")

    router.ServeHTTP(responseRecorder, request)

    if responseRecorder.Code != http.StatusUnsupportedMediaType {
        testing.Errorf("Expected statuscode %d but got %d", http.StatusUnsupportedMediaType, responseRecorder.Code)
    }
}

但测试失败,报错信息:

Expected statuscode 415 but got 201


解决方案

问题根源在于:当请求体为nil时,Chi的AllowContentType中间件会跳过Content-Type的检查逻辑。这是因为HTTP规范中,POST请求如果没有请求体,Content-Type头是可选的,中间件针对这种场景不会触发拦截。

修复方法很简单:给请求添加一个非空的请求体,同时保留错误的Content-Type设置,这样中间件就会正常执行检查逻辑。

修复后的测试代码:

package main

import (
    "net/http"
    "net/http/httptest"
    "strings"
    "testing"
)

func TestGetRouter(t *testing.T) {
    router := GetRouter()

    responseRecorder := httptest.NewRecorder()

    // 添加非空请求体,这里用任意字符串即可
    request, _ := http.NewRequest(http.MethodPost, "/my-route", strings.NewReader("<xml></xml>"))
    request.Header.Set("Content-Type", "text/xml")

    router.ServeHTTP(responseRecorder, request)

    if responseRecorder.Code != http.StatusUnsupportedMediaType {
        t.Errorf("Expected statuscode %d but got %d", http.StatusUnsupportedMediaType, responseRecorder.Code)
    }
}

另外注意测试函数的参数名应该是t *testing.T(原代码写成testing *testing.T是笔误,虽然不影响执行,但不符合Go的编码规范)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 18:01:28