如何在go(golang)中测试未导出的(私有)函数?

Cha*_*ker 45 unit-testing go

我有兴趣在go中创建"未导出(私有)函数"的单元测试.然而,它基本上很难在测试包中形成单元测试,因为我必须使它们"公开".最终,它们打破了他们私密性的全部意义.关键是这些辅助函数有助于模块化,现在它们是模块化的,能够为它们创建单元测试而不会让除了测试包之外的所有人都可以使用它们会很好,很好它们不是应该被访问的函数或者除测试套件或实际包装本身之外的任何人使用.

有什么建议?是否可以导出到自己的包和一个额外的包或类似的东西?

fab*_*ioM 47

在包中创建一个测试文件

library_test.go

package mypkg

func TestPrivateStruct(t *testing.T){
  pf := private{ "Private Field" }
  ....
}
Run Code Online (Sandbox Code Playgroud)

library.go

package mypkg

type private struct {
  privateField string
}
Run Code Online (Sandbox Code Playgroud)

go test mypkg -v 将使用您的私有结构运行您的测试

  • 啊,好问题.go工具支持`...`通配符,所以你可以去测试github.com/yourname/yourrepo/...来测试那里的每个包.(或者像`go test github.com/yourname/...`或`go test crypto/...`,如果你感动的话.) (22认同)
  • @CharlieParker - 是的,但那是Go的标准.您将_test文件和非_test文件混合在一个包中,并测试一些/ path/packagename,而不是某些/ path/packagename/test或some/path/tests/packagename. (7认同)
  • @twotwowo足够公平.但是,它必须去每个目录运行每个去测试它很烦人.是否可以通过某种命令或Make文件或类似的东西运行**所有**测试? (3认同)
  • @CharlieParker `go test ./...` 运行所有测试。如果需要,请记住使用“--tags”。 (2认同)

Maj*_*far 24

如果您想使用 pkg_test 名称作为测试的包名称,并仍然测试未导出的字段,一个简单的技巧可以是在包中使用包名称 pkg 创建 export_test.go 文件,然后在其中导出未导出的字段,例如

文件代码.go

package pkg 

func getFunc(){}
Run Code Online (Sandbox Code Playgroud)

文件export_test.go

package pkg 
var GetFunc = getFunc
Run Code Online (Sandbox Code Playgroud)

文件 code_test.go

package pkg_test
func TestGetFunc(t *testing.T) {
    testFunc:=pkg.GetFunc

    //check your test scenario here

}
Run Code Online (Sandbox Code Playgroud)

请注意,所有这些文件都位于同一文件夹中

该解决方案的灵感来自于这里

  • 这是正确的做法。否则,您要么必须导出仅用于测试的内容,要么让黑盒测试与要测试的代码共享相同的包。 (2认同)

And*_*ips 7

首先,通过使用内部测试的包名称(例如mypkg)并使用相同的包名称为"外部"测试附加" _test "(例如mypkg_test),您可以将两种类型的测试放在与包相同的位置.两种类型的测试必须位于名称以"_test.go"结尾的文件中.

但是,单元测试的重点是测试包的"外部接口"(即公共功能).这是单元测试应该永远是"白盒"测试(见白盒测试).这样你就可以重构你的代码,你的测试也不会破坏.

当然,有时您需要检查内部一致性,这是通过"外部接口"无法实现的.为此,我发现断言非常宝贵.另一种可能性是添加公共"诊断"功能,其名称表明它们不是正常使用的.

  • 单元测试*不仅仅用于公共功能.通常,公共界面可能会因私人​​功能的组合而产生无数不同的期望.对较小的单一用途功能进行单元测试更容易,更安全.你仍然希望明显地测试公共的. (10认同)
  • _带有表示它们不适合正常使用的名称。_---此时,您只是从单元测试中访问内部组件,而是通过调用者可以引导的间接访问层。如果这样做,这是一个明确的标志,“仅限外部”测试并不能满足您的目的。不妨将锹称为锹,然后进入内部。 (2认同)