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

问题描述 投票:0回答:2

尝试奔跑 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

到底是什么问题?

go testing benchmarking channel
2个回答
3
投票

对于这种特定情况,添加 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,
    }
}

3
投票

发生这种情况是因为测试包本身有一个 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,它是一个与 Println 具有相同签名的函数,你可以使用 fmt.Println 进行初始化,在测试中你可以设置为 t.Log 以获得更好的体验

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

© www.soinside.com 2019 - 2024. All rights reserved.