Unable to read variables from a url using gorilla mux in golang
Asked Answered
G

3

5

I am trying to write a unit test using gotests and gomock to my restful service written in golang using gorilla but service fails to get variables from the url

Here is my request

req, err := http.NewRequest("GET", "product/5b5758f9931653c36bcaf0a0", nil)

actual endpoint is product/{id}

when I step into my service at the below code

params := mux.Vars(req)

params map is empty when it should have id key mapped to 5b5758f9931653c36bcaf0a0

Strange part is endpoint works fine from post man.

May I know whats wrong with the request?

Grabble answered 25/7, 2018 at 14:49 Comment(3)
How does the HandleFunce look like?Kroll
I would log request URL and parse it with url.ParseRequestURI to get some info.Manille
log the error you are getting when creating a new requestSubprincipal
G
8

This solved the issue

req = mux.SetURLVars(req, map[string]string{"id": "5b5758f9931653c36bcaf0a0"})
Grabble answered 30/7, 2018 at 16:18 Comment(2)
This is not a solution.Mintz
This is the simplest of the solutions imo. Just do this in your test and voila!Diwan
M
2

Since you're using GET requests, you can use the http.Get function, it works as expected:

package main

import (
    "fmt"
    "net/http"

    "github.com/gorilla/mux"
)

func handle(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    fmt.Println(params)
}

func main() {
    m := mux.NewRouter()
    m.HandleFunc("/products/{id}", handle)
    http.Handle("/", m)
    go func() {
        http.ListenAndServe(":8080", nil)
    }()
    _, err := http.Get("http://localhost:8080/products/765")
    // Handle Error
}

If you really want to use http.NewRequest, that function doesn't actually execute the request so here is what you would need:

req, err := http.NewRequest("GET", "product/5b5758f9931653c36bcaf0a0", nil)
client := &http.Client{}
client.Do(req)
Madore answered 25/7, 2018 at 19:8 Comment(0)
P
1

Create the mux Router in a separate function in the source code and call that directly in your test.

In Source code:

func Router() *mux.Router {
  r := mux.NewRouter()
  r.HandleFunc("/product/{id}", productHandler)

  return r
}

func main() {
http.Handle("/", Router())
}

In Test:

func TestProductHandler(t *testing.T) {
  r := http.NewRequest("GET", "product/5b5758f9931653c36bcaf0a0", nil)
  w := httptest.NewRecorder()

  Router().ServeHTTP(w, r)
}

Found the related solution in one of the google groups forums. https://groups.google.com/forum/#!msg/golang-nuts/Xs-Ho1feGyg/xg5amXHsM_oJ

Putupon answered 22/1, 2020 at 6:20 Comment(1)
yep, this was the correct answer. Thanks!Shuttering

© 2022 - 2024 — McMap. All rights reserved.