gpt4 book ai didi

go - 如何在 go 中使用 martini 测试反向代理

转载 作者:IT王子 更新时间:2023-10-29 01:24:43 58 4
gpt4 key购买 nike

我正在为在 go 中用作反向代理的 martini 应用程序编写测试代码,并想使用 httptest.ResponseRecorder 对其进行测试,但出现以下错误。

[martini] PANIC: interface conversion: *httptest.ResponseRecorder is not http.CloseNotifier: missing method CloseNotify

httptest.ResponseRecorder 没有方法 CloseNotify()

我应该如何测试它?

package main

import (
"github.com/go-martini/martini"
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"net/http/httputil"
"net/url"
"testing"
)

func TestReverseProxy(t *testing.T) {
// Mock backend
backendResponse := "I am the backend"
backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(backendResponse))
}))
defer backend.Close()
backendURL, _ := url.Parse(backend.URL)

// Frontend
m := martini.Classic()
m.Get("/", func(w http.ResponseWriter, r *http.Request) {
proxy := httputil.NewSingleHostReverseProxy(backendURL)
proxy.ServeHTTP(w, r)
})

// Testing
req, _ := http.NewRequest("GET", "/", nil)
res := httptest.NewRecorder()
m.ServeHTTP(res, req)

assert.Equal(t, 200, res.Code, "should be equal")
}

最佳答案

首先,请注意,如他们的 README 中所述,martini 框架不再维护。 .

然后,关于您的问题,这是因为 Martini 做了一些在我看来很糟糕的事情:它需要 http.ResponseWriter并假设它也是一个 http.CloseNotifier ,虽然绝对不能保证这一点。他们应该采用一个自定义接口(interface)来包装它们,就像这样:

type ResponseWriterCloseNotifier interface {
http.ResponseWriter
http.CloseNotifier
}

您可以在他们的源代码中看到他们在自己的测试中遇到了同样的问题,并使用了一些解决方法:https://github.com/go-martini/martini/commit/063dfcd8b0f64f4e2c97f0bc27fa422969baa23b#L13

这是用它编写的一些工作代码:

package main

import (
"net/http"
"net/http/httptest"
"net/http/httputil"
"net/url"
"testing"

"github.com/go-martini/martini"
"github.com/stretchr/testify/assert"
)

type closeNotifyingRecorder struct {
*httptest.ResponseRecorder
closed chan bool
}

func newCloseNotifyingRecorder() *closeNotifyingRecorder {
return &closeNotifyingRecorder{
httptest.NewRecorder(),
make(chan bool, 1),
}
}

func (c *closeNotifyingRecorder) close() {
c.closed <- true
}

func (c *closeNotifyingRecorder) CloseNotify() <-chan bool {
return c.closed
}

func TestReverseProxy(t *testing.T) {
// Mock backend
backendResponse := "I am the backend"
backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(backendResponse))
}))
defer backend.Close()
backendURL, _ := url.Parse(backend.URL)

// Frontend
m := martini.Classic()
m.Get("/", func(w http.ResponseWriter, r *http.Request) {
proxy := httputil.NewSingleHostReverseProxy(backendURL)
proxy.ServeHTTP(w, r)
})

// Testing
req, _ := http.NewRequest("GET", "/", nil)
res := newCloseNotifyingRecorder()
m.ServeHTTP(res, req)

assert.Equal(t, 200, res.Code, "should be equal")
}

关于go - 如何在 go 中使用 martini 测试反向代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33968840/

58 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com