Golang httptest服务器循环依赖

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

Golang httptest server circular dependency

问题

我想为一个函数编写一个测试,该函数执行以下操作:

  1. 发送一个 Get 请求到 url1,该请求会获取到 url2。
  2. 发送一个 Get 请求到 url2,并返回结果。

但是我不确定如何模拟 url2 的返回值,因为在服务器启动之前我无法获取到 server.URL。但是在服务器启动之后,我又无法更改处理程序。例如,运行下面的代码会出现错误 Get /url2: unsupported protocol scheme ""

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
)

func myFunc(client *http.Client, url1 string) string {
	url2 := get(client, url1)
	return get(client, url2)
}

func get(client *http.Client, url string) string {
	resp, err := client.Get(url)
	if err != nil {
		fmt.Println(err)
	}
	body, err := ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()
	if err != nil {
		fmt.Println(err)
	}
	return string(body)
}

// 测试 myFunc
func main() {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch r.URL.String() {
		case "/url1":
			w.Write([]byte("/url2")) // 在这里如何指定 srv.URL+"/url2"?
		case "/url2":
			w.Write([]byte("返回数据"))
		}
	}))
	defer srv.Close()

	myFunc(srv.Client(), srv.URL+"/url1")
}

来源:https://onlinegdb.com/UpKlXfw45

英文:

I'd like to write a test for a function that

  1. Makes a Get request to url1, which retrieves url2
  2. Makes a Get request to url2, and returns the result

But I'm not sure how to mock the return value for url2, since I cannot fetch the server.URL before the server is started. But after the server is started I cannot change the handler. Eg, running the below gives error Get /url2: unsupported protocol scheme ""

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
)

func myFunc(client *http.Client, url1 string) string {
	url2 := get(client, url1)
	return get(client, url2)
}

func get(client *http.Client, url string) string {
	resp, err := client.Get(url)
	if err != nil {
		fmt.Println(err)
	}
	body, err := ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()
	if err != nil {
		fmt.Println(err)
	}
	return string(body)
}

// test myFunc
func main() {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch r.URL.String() {
		case "/url1":
			w.Write([]byte("/url2")) // how to specify srv.URL+"/url2" here?
		case "/url2":
			w.Write([]byte("return data"))
		}
	}))
	defer srv.Close()

	myFunc(srv.Client(), srv.URL+"/url1")
}

Source: https://onlinegdb.com/UpKlXfw45

答案1

得分: 2

在使用变量之前声明srv变量。

var srv *httptest.Server
srv = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    switch r.URL.String() {
    case "/url1":
        w.Write([]byte(srv.URL + "/url2"))
    case "/url2":
        w.Write([]byte("return data"))
    }
}))
英文:

Declare the srv variable before using the variable.

var srv *httptest.Server
srv = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	switch r.URL.String() {
	case "/url1":
		w.Write([]byte(srv.URL + "/url2")) 
	case "/url2":
		w.Write([]byte("return data"))
	}
}))

huangapple
  • 本文由 发表于 2022年5月29日 08:32:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/72420165.html
匿名

发表评论

匿名网友

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

确定