如何用go中的martini测试反向代理

时间:2015-11-28 07:25:36

标签: go reverse-proxy 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")
}

1 个答案:

答案 0 :(得分:6)

首先,请注意马丁尼框架不再像README中那样进行维护。

然后,关于你的问题,因为Martini做了一件看起来很糟糕的事情:它需要http.ResponseWriter并假设它也是http.CloseNotifier,而绝对没有保证这一点。他们应该采用自定义界面包装它们,如下所示:

<div class="background-image first-child">
  <!-- Empty block -->
</div>

<div class="background-image last-child">
  <!-- Empty block -->
</div>

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

以下是一些使用它制作的代码:

type ResponseWriterCloseNotifier interface {
    http.ResponseWriter
    http.CloseNotifier
}