为了账号安全,请及时绑定邮箱和手机立即绑定

去单元测试致命和测试 main()

去单元测试致命和测试 main()

Go
慕桂英3389331 2022-01-17 18:45:17
我很新去测试来自 PHP 的背景和 PHPUnit 测试。在 PHP 中,非常可靠地宣扬您需要 100% 的覆盖率。在 Go 中,我读过的大多数关于测试的东西似乎很少,没有像引发错误这样的东西。例如我的小程序:func main() {    config = readConfig("config.json")}func readConfig(path string) Config {    var cfg Config    file, err := ioutil.ReadFile(path)    if err != nil {        log.Fatal(err)    }    err = json.Unmarshal(file, &cfg)    if err != nil {        log.Fatal(err)    }    return cfg}func TestCanReadConfig(t *testing.T) {    cfg := readConfig("test_data/config.json")    if cfg.Broker_pass != "test" || cfg.Broker_port != "3333" {        t.Error("invalid config")    }}现在在我的示例中,我会遇到覆盖问题,因为单元测试中根本没有涵盖 main()(应该如何处理?)并且 2 log.Fatal() 根本不包括在内。我的问题是如何在 go 中准确地编写测试?我是否以一种不太严格的方式来做,而不是测试每一个可能的场景,或者我可以像在 php 中那样使用 @expectedException \InvalidArgumentException Can I 还是应该测试 main 函数进行注释?如果不是,我可以以某种方式从覆盖工具中忽略它吗?我应该考虑一个测试框架吗?大多数测试教程都很好,但很短,只介绍简单的测试。
查看完整描述

1 回答

?
隔江千里

TA贡献1906条经验 获得超10个赞

它本身不是 Go 的东西,这取决于您的偏好,但是:


一个。不要测试main。main 应该只调用经过测试的代码,最好是在其他包中。为这些包提供尽可能多的代码覆盖率,并尽可能让 main 变得微不足道。无论覆盖范围如何,这是一个很好的做法。所以这不是一个真正的问题。


湾。不要log.Fatal用于可测试的代码,只返回错误。您可以保留log.Fatal应用程序初始化代码,即 - in main:)。因此,如果 main 调用readConfig失败,它只会返回一个错误(非常可测试!)。添加的应用程序行为log.Fatal是 main 的工作——配置读取器不应该处理诸如决定我们是否应该退出应用程序之类的事情,对吧?它只是读取配置并告诉您它是否成功。应用程序决定如何处理它。


所以你的代码可能看起来像:


func readConfig(path string) (Config, error) {

    var cfg Config

    file, err := ioutil.ReadFile(path)

    if err != nil {

        return cfg, err

    }

    err = json.Unmarshal(file, &cfg)

    if err != nil {

        return cfg, err

    }

    return cfg, nil

}


func main() {

    config, err := readConfig("config.json")

    if err != nil {

        log.Fatal(err)

    }


}

现在您已经将逻辑与应用程序行为分离,并且readConfig完全可测试。


查看完整回答
反对 回复 2022-01-17
  • 1 回答
  • 0 关注
  • 175 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信