Anshul Sharma
Anshul Sharma

Reputation: 1123

How to pass path param to httptest request

I am writing the unit test case for my http APIs, i need to pass the path param to the API endpoint

GetProduct(w http.ResponseWriter, r *http.Request) {
    uuidString := chi.URLParam(r, "uuid")
    uuid1, err := uuid.FromString(uuidString)
    if err != nil {
        w.WriteHeader(http.StatusBadRequest)
        _, _ = w.Write([]byte(err.Error()))
        return
    }
}

I need to test this method and for that i need to pass a valid uuid to r http.Request, please suggest how can i do that, I tried a few options from my test class like

req.URL.Query().Set("uuid", "valid_uuid") 

But it did not work. How can I test this method by passing a valid uuid to request?

Upvotes: 1

Views: 4306

Answers (1)

ossan
ossan

Reputation: 1865

Let me present my usual solution with gorilla package.

handler.go file

package httpunittest

import (
    "net/http"

    "github.com/gorilla/mux"
)

func GetProduct(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    uuidString, isFound := params["uuid"]
    if !isFound {
        w.WriteHeader(http.StatusBadRequest)
        return
    }
    w.Write([]byte(uuidString))
}

Here, you use the function Vars to fetch all of the URL parameters present within the http.Request. Then, you've to look for the uuid key and do your business logic with it.

handler_test.go file

package httpunittest

import (
    "net/http"
    "net/http/httptest"
    "testing"

    "github.com/gorilla/mux"
    "github.com/stretchr/testify/assert"
)

func TestGetProduct(t *testing.T) {
    t.Run("WithUUID", func(t *testing.T) {
        r := httptest.NewRequest(http.MethodGet, "/products/1", nil) // note that this URL is useless
        r = mux.SetURLVars(r, map[string]string{"uuid": "1"})
        w := httptest.NewRecorder()

        GetProduct(w, r)

        assert.Equal(t, http.StatusOK, w.Result().StatusCode)
    })

    t.Run("Without_UUID", func(t *testing.T) {
        r := httptest.NewRequest(http.MethodGet, "/products", nil) // note that this URL is useless
        w := httptest.NewRecorder()

        GetProduct(w, r)

        assert.Equal(t, http.StatusBadRequest, w.Result().StatusCode)
    })
}

First, I used the functions provided by the httptest package of the Go Standard Library that fits well for unit testing our HTTP handlers.
Then, I used the function SetUrlVars provided by the gorilla package that allows us to set the URL parameters of an http.Request.
Thanks to this you should be able to achieve what you need!

Upvotes: 3

Related Questions