作为我的第一个项目的一部分,我正在创建一个小型库,以便向任何用户发送短信。如果第一次没有收到正状态,我已经添加了等待和重试的逻辑。这是对SMS发送服务的基本HTTP调用。我的算法看起来像这样(注释可以解释代码的流程):
for {
//send request
resp, err := HTTPClient.Do(req)
checkOK, checkSuccessUrl, checkErr := CheckSuccessStatus(resp, err)
//if successful don't continue
if !checkOK and checkErr != nil {
err = checkErr
return resp, SUCCESS, int8(RetryMax-remain+1), err
}
remain := remain - 1
if remain == 0 {
break
}
//calculate wait time
wait := Backoff(RetryWaitMin, RetryWaitMax, RetryMax-remain, resp)
//wait for time calculated in backoff above
time.Sleep(wait)
//check the status of last call, if unsuccessful then continue the loop
if checkSuccessUrl != "" {
req, err := GetNotificationStatusCheckRequest(checkSuccessUrl)
resp, err := HTTPClient.Do(req)
checkOK, _, checkErr = CheckSuccessStatusBeforeRetry(resp, err)
if !checkOK {
if checkErr != nil {
err = checkErr
}
return resp,SUCCESS, int8(RetryMax-remain), err
}
}
}
现在我想使用任何可用的HTTP模拟框架来测试这个逻辑。我得到的最好的是https://github.com/jarcoal/httpmock
但是这个没有提供分别模拟第一个和第二个URL的响应的功能。因此,我无法测试第二次或第三次重试的成功。我可以先测试成功,也可以完全失败。
是否有适合我测试此特定功能需求的套餐?如果不是,我如何使用当前工具实现这一目标?
答案 0 :(得分:0)
使用标准库httptest package中的测试服务器可以轻松实现这一点。稍微修改其中包含的示例,您可以通过这样做为您预先想要的每个响应设置功能:
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
)
func main() {
responseCounter := 0
responses := []func(w http.ResponseWriter, r *http.Request){
func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "First response")
},
func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Second response")
},
}
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
responses[responseCounter](w, r)
responseCounter++
}))
defer ts.Close()
printBody(ts.URL)
printBody(ts.URL)
}
func printBody(url string) {
res, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
resBody, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", resBody)
}
哪个输出:
First response
Second response
此处的可执行代码: