英文:
golang gorilla/mux and testing, where to store routes
问题
在我看过的大部分文档中,建议使用gorilla mux的方式如下:
func main() {
m := mux.Router()
m.HandleFunc("/", FuncNameOrDef)
http.ListenAndServe(":8080", m)
}
这样做很好,但是这给我留下了一个问题,因为根据我所见,为了进行测试,我需要重新声明mux和路由,除非我在函数外部声明mux和路由,像这样:
var (
m = mux.Router()
_ = m.HandleFunc("/", FuncNameOrDef)
)
然后在我的测试中这样做:
func TestSomeView(t *testing.T) {
ts := httptest.NewServer(m)
// 进行测试
}
这解决了问题,但是这样会使包看起来相当丑陋(有很多_ = m.HandleFunc
)。有没有更符合惯例的方法来做这个?
英文:
In most of the docs I have seen, gorilla mux is suggested to be used like so...
func main() {
m := mux.Router()
m.HandleFunc("/", FuncNameOrDef)
http.ListenAndServe(":8080", m)
}
which is great, but it leaves me with a problem, because then in order to test, as far as I can see, I need to redeclare mux and routes unless I declare mux and routes outside of a function like this...
var (
m = mux.Router()
_ = m.HandleFunc("/", FuncNameOrDef)
)
and then in my tests do this...
func TestSomeView(t *testing.T) {
ts := httptest.NewServer(m)
....testing blah
}
which solves the problem, but then it makes the package pretty ugly (with all the _ = m.HandleFunc
's) Is there a more idiomatic way to do this?
答案1
得分: 4
你可以使用一个工厂函数来为你的应用程序创建一个新的http.Handler
。这样可以让你以编程方式定义处理程序,并在测试中重用它们。
// NewApplicationHandler为应用程序提供一个配置好的处理程序。
func NewApplicationHandler() http.Handler {
mux := mux.NewRouter()
mux.HandleFunc("/", handler)
return mux
}
func handler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World!"))
}
这个示例可以在测试中这样使用:
func TestApplicationServeMux(t *testing.T) {
// 通过调用工厂函数获取处理程序。
applicationHandler := NewApplicationHandler()
ts := httptest.NewServer(applicationHandler)
defer ts.Close()
res, err := http.Get(ts.URL)
if err != nil {
t.Fatalf("%s", err)
}
defer res.Body.Close()
greeting, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatalf("%s", err)
}
want := []byte("Hello World!")
if !bytes.Equal(want, greeting) {
t.Errorf("Expected greeting %s; got %s", want, greeting)
}
}
英文:
You could use a factory function to create a new http.Handler
for you application. This would allow you to programmatically define the handlers and reuse them in the tests.
// NewApplicationHandler provides a configured handler for the
// application.
func NewApplicationHandler() http.Handler {
mux := mux.NewRouter()
mux.HandleFunc("/", handler)
return mux
}
func handler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World!"))
}
This example would be utilized in a test like so:
func TestApplicationServeMux(t *testing.T) {
// The handlers are being obtained via a call to the factory function.
applicationHandler := NewApplicationHandler()
ts := httptest.NewServer(applicationHandler)
defer ts.Close()
res, err := http.Get(ts.URL)
if err != nil {
t.Fatalf("%s", err)
}
defer res.Body.Close()
greeting, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatalf("%s", err)
}
want := []byte("Hello World!")
if !bytes.Equal(want, greeting) {
t.Errorf("Expected greeting %s; got %s", want, greeting)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论