【发布时间】:2018-10-09 09:40:38
【问题描述】:
作为我第一个项目的一部分,我正在创建一个小型库来向任何用户发送 SMS。如果第一次没有收到肯定状态,我添加了等待和重试的逻辑。这是对短信发送服务的基本 HTTP 调用。我的算法是这样的(cmets 会解释代码的流程):
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 响应的功能。因此,我无法在第二次或第三次重试中测试成功。我可以先测试成功,也可以完全失败。
是否有适合我测试此特定功能的需要的软件包?如果不是,我如何使用当前工具实现这一目标?
【问题讨论】:
-
您可以定义一个最小接口来返回您期望从 http 调用或错误中返回的数据,而不是模拟 http 请求。然后你可以做一个在成功之前失败几次的测试实现。
-
我把它作为最后的手段。因为,我可能必须使用所述最小接口扩展/使用我当前的类,这将改变我的代码的当前结构。没有用于这些目的的成熟模拟框架吗?类似于 Java 中的 mockito:static.javadoc.io/org.mockito/mockito-core/2.10.0/org/mockito/…
-
我使用了来自github.com/stretchr/testify 和github.com/vektra/mockery 的模拟包来生成模拟代码。不确定它是否具有您想要的功能。我发现使用起来很麻烦。我认为一般来说,mock 在 go 中不被认为是一种很好的实践,使用简单的接口和测试实现更加地道。当然是 YMMV。
-
“但是这个不提供分别模拟第一个和第二个 url 的响应的功能。”当然可以,您可以传递具有自定义逻辑的函数,如您页面上的高级示例中所述链接。
-
它看起来会工作,我会试一试。感谢您的建议。
标签: go mocking retrypolicy retry-logic http-mock