简体   繁体   中英

Testing Handler Function that relies on a dynamic URL in Go

I have been searching around for an answer, but I can't find it. My question is, is it possible to test a handler function that relies on a dynamic URL token?

For example, lets say my handler function requires a token from the URL that is dynamically generated (I don't know how the token is generated nor do I have access to it aside from the URL parameter). My URL would always look something like this: www.example.com/?token=randomtokenhere

func TokenProcessing(w http.ResponseWriter, r *http.Request) {
     token := r.URL.Query().Get("token") // dynamically generated from parsed URL 

      // code to do something with said token

}

Is possible to somehow unit test this handler function without access to how the token is created?

You can populate the query parameters of a http.Request and then test the handler with a httptest.ResponseRecorder

eg

package main

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

// In this test file to keep the SO example concise
func TokenProcessing(w http.ResponseWriter, r *http.Request) {
    token := r.URL.Query().Get("token") // dynamically generated from parsed URL
    // code to do something with said token
    log.Println(token)
}

func TestTokenProcessing(t *testing.T) {
    rr := httptest.NewRecorder()
    r, err := http.NewRequest("GET", "http://golang.org/", nil)
    if err != nil {
        t.Fatal(err)
    }

    // Generate suitable values here - e.g. call your generateToken() func
    r.URL.Query().Add("token", "someval")

    handler := http.HandlerFunc(TokenProcessing)
    handler.ServeHTTP(rr, r)

    if code := rr.Code; code != http.StatusOK {
        t.Fatalf("handler did not return correct status: want %v got %v",
            http.StatusOK, code)
    }

    // Test the rest of the response - i.e. sets a header, etc.
}

The easiest thing I can think of to do would be to create a helper function which takes all of the arguments as the handler, and additionally takes the token as an argument. Then you can unit test that function instead. So something like:

func TokenProcessing(w http.ResponseWriter, r *http.Request) {
    token := r.URL.Query().Get("token")
    tokenProcessingHelper(w, r, token)
}

// unit test me!
func tokenProcessingHelper(w http.ResponseWriter, r *http.Request, token string) {
    ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM