如何在创建测试请求时模拟一个简单的POST请求体?

huangapple go评论143阅读模式
英文:

How do I mock a simple POST body when creating a test request

问题

我正在尝试为一个简单的表单处理程序编写单元测试。我找不到任何关于如何创建表单主体的信息,以便它能够被我的处理程序中的r.ParseForm()捕获。我可以自己查看和读取主体,但是在我的测试中,当它在我的应用程序中按预期工作时,r.Form总是url.Values{}

代码可以简化为以下示例:

package main

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

func main() {
	w := httptest.NewRecorder()
	r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader("a=1&b=2"))
	handler(w, r)
}

func handler(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	fmt.Printf("form: %#v\n", r.Form)
}

当我期望它打印:

form: url.Values{"a": []string{"1"}, "b": []string{"2"}}

我应该如何将主体传递给httptest.NewRequest,以便它被r.ParseForm捕获?

英文:

I'm trying to write a unit test for a simple form handler. I cannot find any info on how to create the form body in a way that it is being picked up by r.ParseForm() in my handler. I can see and read from the body myself, but r.Form in my test will always be url.Values{} when it works as expected in my application.

The code boils down to the following example:

package main

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

func main() {
	w := httptest.NewRecorder()
	r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader("a=1&b=2"))
	handler(w, r)
}

func handler(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	fmt.Printf("form: %#v\n", r.Form)
}

that prints

form: url.Values{}

when I'd expect it to print:

form: url.Values{"a": []string{"1"}, "b": []string{"2"}}

How do I actually pass the body to httptest.NewRequest so that it gets picked up by r.ParseForm?

答案1

得分: 11

你只需要在请求中设置Content-Type头部。

package main

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

func main() {
	w := httptest.NewRecorder()
	r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader("a=1&b=2"))
	r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	handler(w, r)
}

func handler(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	fmt.Printf("form: %#v\n", r.Form)
}

链接:https://play.golang.org/p/KLhNHbbNWl

英文:

You just need to set the Content-Type header on the request.

package main

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

func main() {
	w := httptest.NewRecorder()
	r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader("a=1&b=2"))
	r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	handler(w, r)
}

func handler(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	fmt.Printf("form: %#v\n", r.Form)
}

https://play.golang.org/p/KLhNHbbNWl

huangapple
  • 本文由 发表于 2017年8月29日 23:20:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/45942832.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定