测试依赖于动态URL的Go处理程序函数。

huangapple go评论97阅读模式
英文:

Testing Handler Function that relies on a dynamic URL in Go

问题

我一直在寻找答案,但找不到。我的问题是,是否有可能测试一个依赖于动态URL令牌的处理函数?

例如,假设我的处理函数需要从动态生成的URL中获取一个令牌(我不知道令牌是如何生成的,除了URL参数之外我也无法访问它)。我的URL看起来总是像这样:www.example.com/?token=randomtokenhere

func TokenProcessing(w http.ResponseWriter, r *http.Request) {
     token := r.URL.Query().Get("token") // 从解析的URL中动态生成
     
     // 使用该令牌进行某些操作的代码

}

是否有可能在没有访问令牌生成方式的情况下对这个处理函数进行单元测试?

英文:

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?

答案1

得分: 2

你可以填充http.Request的查询参数,然后使用httptest.ResponseRecorder来测试处理程序。

例如:

package main

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

// 在这个示例中,为了简洁起见,将测试代码放在同一个文件中
func TokenProcessing(w http.ResponseWriter, r *http.Request) {
	token := r.URL.Query().Get("token") // 从解析的URL中动态生成
	// 处理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)
	}

	// 在这里生成合适的值 - 例如调用你的generateToken()函数
	r.URL.Query().Add("token", "someval")

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

	if code := rr.Code; code != http.StatusOK {
		t.Fatalf("处理程序没有返回正确的状态码: 期望 %v 实际 %v",
			http.StatusOK, code)
	}

	// 测试响应的其余部分 - 例如设置头部等
}

以上是要翻译的内容。

英文:

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

e.g.

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.
}

答案2

得分: 1

我可以想到的最简单的方法是创建一个辅助函数,将所有参数作为处理程序的参数,并额外将令牌作为参数传入。然后,您可以对该函数进行单元测试。代码示例如下:

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) {
    ...
}

这样,您可以对tokenProcessingHelper函数进行单元测试。

英文:

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) {
    ...
}

huangapple
  • 本文由 发表于 2015年8月8日 09:30:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/31888744.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定