Unit testing 什么';在Go中使用HTTP请求测试函数最惯用的方法是什么?

Unit testing 什么';在Go中使用HTTP请求测试函数最惯用的方法是什么?,unit-testing,go,testing,testify,Unit Testing,Go,Testing,Testify,我有一个有趣的小天气应用程序。每天只需99美元,该应用程序就能每天查看天气,如果西雅图下雨,就给圣地亚哥的人们送一把雨伞 我使用这两个功能作为我的应用程序的一部分: func IsRaining() (bool, error) { resp, err := http.Get("https://isitraining.in/Seattle") if err != nil { return false, fmt.Errorf("could

我有一个有趣的小天气应用程序。每天只需99美元,该应用程序就能每天查看天气,如果西雅图下雨,就给圣地亚哥的人们送一把雨伞

我使用这两个功能作为我的应用程序的一部分:

func IsRaining() (bool, error) {
    resp, err := http.Get("https://isitraining.in/Seattle")
    if err != nil {
        return false, fmt.Errorf("could not fetch raining status: %w", err)
    }

    parsed, err := weather.Parse(resp)
    if err != nil {
        return false, fmt.Errorf("could not parse the weather: %w", err)
    }

    return parsed.IsRaining, nil
}

func SendUmbrella() error {
    postData := umbrellaPostData()
    resp, err := http.Post("https://amazon.com", "text/html", &postData)
    if err != nil {
        return fmt.Errorf("could not send umbrella: %w", err)
    }
    return nil
}
我想测试
IsRaining()
sendwarrella()
,但我不想每次运行测试时都给别人送伞;我的工程师使用TDD,你知道,我有预算。
IsRaining()
也是一样,如果互联网断开了怎么办?无论晴雨,我仍然需要能够通过测试跑步

我想这样做,代码保持人体工程学和可读性,但我肯定需要能够测试那些依赖HTTP的功能。在围棋中最惯用的方法是什么

我用的是。请在评论中告诉我,我是如何失去了对惯用围棋的希望的:)

我不知道“最惯用”是什么,但与任何其他语言一样,硬编码类软件包令人头痛。不要直接在http包上调用方法,而是创建一个httpClient接口。然后模拟httpClient接口

您可以将httpClient传递到函数中,但将它们转换为结构上的方法更有意义

//为http客户端设置一个接口,与http.client相同。
类型httpClient接口{
获取(字符串)(*http.Response,错误)
}
//制作一个用于挂起客户端和方法的结构。
类型雨伞给定器结构{
客户端httpClient
}
//一个简化的示例方法。
func(给定者雨伞给定者)getExample()([]字节,错误){
resp,err:=giver.client.Get(“https://example.com")
如果错误!=零{
返回零,错误
}
延迟响应主体关闭()
返回io.ReadAll(分别为正文)
}
然后一个模拟的httpClient就可以放进你的雨伞了

//我们的模拟客户端。
类型mockedClient结构{
模仿,模仿
}
//定义基本mocked Get方法以记录其参数和
//返回其模拟值。
func(m mockedClient)Get(url字符串)(*http.Response,错误){
args:=m.Called(url)
如果args.Get(0)=nil{
返回nil,参数错误(1)
}否则{
返回args.Get(0)。(*http.Response),args.Error(1)
}
}
func main(){
//制作一个mockedClient并设置一个期望值。
客户端:=新建(mockedClient)
//制作一个使用模拟客户的雨伞赠送者。
s:=雨伞给予者{客户:客户}
//让我们测试一下调用失败时会发生什么。
客户,开(
“得到”https://example.com",
).返回(
无,错误。新建(“系统关闭”),
)
body,err:=s.getExample()
如果错误!=零{
恐慌(错误)
}
格式打印F(“%s”,正文)
}

请看

我在构思你的问题时投票赞成独创性!另外,为了真正回答您的问题:通过模拟您的HTTP客户机:-本文的最终结论可以总结为:使用依赖注入并仅通过接口与服务交互(其中“服务”类似于HTTP客户机类型,而不是web服务)。顺便说一句,这可能会让你开始一场大规模的重构狂欢——特别是当你的应用程序还没有使用DI的时候。不幸的是,我不相信Golang有一个固执己见的DI容器。。。lemme checkUPDATE:从这个问题来看,Go社区似乎还没有找到一个好的DI解决方案:尽管谷歌在2018年推出了自己的DI容器:考虑到你的使用情况,isRaining不能总是返回true吗?使用证明与“惯用”相反,那么为什么还要麻烦呢?