恐慌:测试:在 Go 中的 Init 案例之前调用 Verbose

发布于 2025-01-17 04:11:59 字数 613 浏览 2 评论 0原文

尝试跑步 https://github.com/adonovan/gopl。 io/blob/master/ch8/cake/cake_test.go

但得到

panic: testing: Verbose called before Init

goroutine 1 [running]:
testing.Verbose(...)
  /usr/lib/go-1.17/src/testing/testing.go:453
.../cake_test.init()

它说错误来自 cake_test.init(),但 cake_test.go文件不包含 init()

$ grep init cake_test.go | wc
      0       0       0

到底是什么问题?

Trying to run
https://github.com/adonovan/gopl.io/blob/master/ch8/cake/cake_test.go

but got

panic: testing: Verbose called before Init

goroutine 1 [running]:
testing.Verbose(...)
  /usr/lib/go-1.17/src/testing/testing.go:453
.../cake_test.init()

It says the error comes from cake_test.init(), yet the cake_test.go file doesn't contain init():

$ grep init cake_test.go | wc
      0       0       0

What exactly is the problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

感性 2025-01-24 04:11:59

对于这种特定情况,添加 Init() 函数就可以解决问题。

var defaults cake.Shop

func Init() {
    defaults = cake.Shop{
        Verbose:      testing.Verbose(),
        Cakes:        20,
        BakeTime:     10 * time.Millisecond,
        NumIcers:     1,
        IceTime:      10 * time.Millisecond,
        InscribeTime: 10 * time.Millisecond,
    }
}

For this specific case, adding Init() function did the trick.

var defaults cake.Shop

func Init() {
    defaults = cake.Shop{
        Verbose:      testing.Verbose(),
        Cakes:        20,
        BakeTime:     10 * time.Millisecond,
        NumIcers:     1,
        IceTime:      10 * time.Millisecond,
        InscribeTime: 10 * time.Millisecond,
    }
}
心房敞 2025-01-24 04:11:59

发生这种情况是因为测试包本身有一个 init 来处理测试标志,并且您正在调用 Verbose 来创建全局变量

https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/testing/testing.go;l=548

要避免这种情况,您可以:

  1. 使用ponter 到函数来捕获测试。详细并在所有初始化之后使用内部函数(详细将是类型 func() bool ),但我认为这很复杂
  2. 添加一个帮助器,在每个函数上创建一个新的默认值通过安全调用testing.Verbose
  3. 创建一个构造函数(而不是测试助手)来填充最常见的选项,您可以在每个测试上设置 Verbose 的值
  4. 创建两个构造函数,第二个构造函数接收 Verbose 的值

另外,考虑创建一个具有与 Println 相同签名的方法 Debug ,如果 Verbose 为 true 则调用 fmt.Println 如果

您有一个构造函数,您可以创建第二个字段:Logger,它是一个函数的ponter和与 Println 相同的签名,并使用 fmt.Println 进行初始化,在测试中,您可以设置为 t.Log 以获得更好的体验

当然,也许有些建议比其他建议更先进,请随意尝试一下并选择最好的

This happens because the testing package itself has a init to process test flags and you are callind Verbose to create a global variable

https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/testing/testing.go;l=548

To avoid this you can:

  1. Use a ponter to function to capture testing.Verbose and use inside functions, after all initializations ( Verbose will be type func() bool) but I think this is complex
  2. Add a helper that creates a new default on each test with a safe call to testing.Verbose
  3. Create a constructor (instead a test helper) that fill with the most common options and you can set the value of Verbose on each test
  4. Create a two constructors, a second one that receive the value of Verbose

Also, Consider create a method Debug with same signature of Println, to call fmt.Println if Verbose is true

If you have a constructor, you can create a second field: Logger, with is a ponter to function with same signature as Println and you initialize with fmt.Println and in the tests you can set as t.Log to have a better experience

Of course perhaps some suggestions are more advanced than others, feel free to play a little bit and choose the best ones

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文