Here's what I'm trying to do :
main.go
package main
import (
"fmt"
"net/http"
"http://ift.tt/J9WoXt"
)
func main() {
mainRouter := mux.NewRouter().StrictSlash(true)
mainRouter.HandleFunc("/test/{mystring}", GetRequest).Name("/test/{mystring}").Methods("GET")
http.Handle("/", mainRouter)
err := http.ListenAndServe(":8080", mainRouter)
if err != nil {
fmt.Println("Something is wrong : " + err.Error())
}
}
func GetRequest(w http.ResponseWriter, r *http.Request) {
if r.Body == nil {
return
} else {
defer r.Body.Close()
}
vars := mux.Vars(r)
myString := vars["mystring"]
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte(myString))
}
This creates a basic http server listening on port 8080 that echoes the URL parameter given in the path. So for http://localhost:8080/test/abcd it will write back a response containing abcd in the response body.
The unit test for the GetRequest() function is in main_test.go :
package main
import (
"net/http"
"net/http/httptest"
"testing"
"http://ift.tt/1mEaz84"
"http://ift.tt/1qjqyGz"
)
func TestGetRequest(t *testing.T) {
t.Parallel()
r, _ := http.NewRequest("GET", "/test/abcd", nil)
w := httptest.NewRecorder()
//Hack to try to fake gorilla/mux vars
vars := map[string]string{
"mystring": "abcd",
}
context.Set(r, 0, vars)
GetRequest(w, r)
assert.Equal(t, http.StatusOK, w.Code)
assert.Equal(t, []byte("abcd"), w.Body.Bytes())
}
The test result is :
--- FAIL: TestGetRequest (0.00s)
assertions.go:203:
Error Trace: main_test.go:27
Error: Not equal: []byte{0x61, 0x62, 0x63, 0x64} (expected)
!= []byte(nil) (actual)
Diff:
--- Expected
+++ Actual
@@ -1,4 +1,2 @@
-([]uint8) (len=4 cap=8) {
- 00000000 61 62 63 64 |abcd|
-}
+([]uint8) <nil>
FAIL
FAIL command-line-arguments 0.037s
The question is how do I fake the mux.Vars(r) for the unit tests? I've found some discussions here but the proposed solution no longer works. The proposed solution was :
func buildRequest(method string, url string, doctype uint32, docid uint32) *http.Request {
req, _ := http.NewRequest(method, url, nil)
req.ParseForm()
var vars = map[string]string{
"doctype": strconv.FormatUint(uint64(doctype), 10),
"docid": strconv.FormatUint(uint64(docid), 10),
}
context.DefaultContext.Set(req, mux.ContextKey(0), vars) // mux.ContextKey exported
return req
}
This solution doesn't work since context.DefaultContext and mux.ContextKey no longer exist.
Another proposed solution would be to alter your code so that the request functions also accept a map[string]string as a third parameter. Other solutions include actually starting a server and building the request and sending it directly to the server. In my opinion this would defeat the purpose of unit testing, turning them essentially into functional tests.
Considering the fact the the linked thread is from 2013.
Aucun commentaire:
Enregistrer un commentaire