Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 893
m90 Avatar asked Aug 29 '17 15:08

m90


1 Answers

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

like image 79
mkopriva Avatar answered Oct 06 '22 01:10

mkopriva