【发布时间】:2021-07-21 06:48:50
【问题描述】:
我有一个有趣的小天气应用程序。只需 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() 和SendUmbrella(),但我不想每次运行测试时都需要送伞;我的工程师使用 TDD,我确实有预算,你知道的。与IsRaining() 相同,如果互联网中断了怎么办?我仍然需要能够经受住考验,风雨无阻。
我想以这样一种方式来做这件事,即代码保持符合人体工程学和可读性,但我肯定需要能够测试那些依赖于 HTTP 的函数。在 Go 中最惯用的方法是什么?
附:我正在使用Testify。告诉我所有关于我如何在 cmets 中失去惯用 Go 的希望 :)
【问题讨论】:
-
我在设计您的问题时赞成原创性!
-
另外,要实际回答您的问题:通过模拟您的 HTTP 客户端:thegreatcodeadventure.com/mocking-http-requests-in-golang - 文章的最终结论可以概括为:使用依赖注入并与服务交互(其中“服务”是类似于 HTTP 客户端类型 - 不是 Web 服务)仅通过接口。顺便说一句,这可能会让你开始一场重大的重构狂欢——尤其是在你的应用程序还没有使用 DI 的情况下。不幸的是,我不相信 Golang 带有自以为是的 DI 容器... lemme check
-
更新:从这个问题来看,Go 社区似乎还没有找到一个好的 DI 解决方案:stackoverflow.com/questions/41900053/… 尽管谷歌在 2018 年推出了自己的 DI 容器:blog.golang.org/wire
-
鉴于您的用例,isRaining 不能总是返回 true 吗?
-
使用 testify 是“惯用”的反面,那何必呢?
标签: unit-testing go testing testify