DoIt
DoIt

Reputation: 3428

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

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?

Upvotes: 5

Views: 3180

Answers (3)

Raviteja
Raviteja

Reputation: 2022

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

Upvotes: 1

DoIt
DoIt

Reputation: 3428

This solved the issue

req = mux.SetURLVars(req, map[string]string{"id": "5b5758f9931653c36bcaf0a0"})

Upvotes: 8

MarcusOuelletus
MarcusOuelletus

Reputation: 149

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)

Upvotes: 2

Related Questions