在Go语言中,测试私有函数的惯用方式是通过包内测试(internal test)或使用导出包装器。以下是具体做法和命名规范:
1. 包内测试(推荐方式)
将测试文件放在与被测试文件相同的包中(而不是_test包),这样可以直接访问私有函数:
// file: mypackage/mypackage.go
package mypackage
func doStuff() string {
return "private result"
}
func PublicFunc() string {
return doStuff()
}
// file: mypackage/mypackage_test.go
package mypackage // 注意:不是 mypackage_test
import "testing"
func TestDoStuff(t *testing.T) {
result := doStuff() // 可以直接访问私有函数
expected := "private result"
if result != expected {
t.Errorf("doStuff() = %q, want %q", result, expected)
}
}
测试函数命名使用:TestDoStuff()
2. 使用导出包装器
如果坚持使用_test包,可以通过导出函数间接测试:
// file: mypackage/mypackage.go
package mypackage
func doStuff() string {
return "private result"
}
// 导出包装器用于测试
var TestDoStuff = doStuff
// file: mypackage/mypackage_test.go
package mypackage_test
import (
"testing"
"mypackage"
)
func TestDoStuff(t *testing.T) {
result := mypackage.TestDoStuff() // 通过导出变量访问
expected := "private result"
if result != expected {
t.Errorf("doStuff() = %q, want %q", result, expected)
}
}
3. 命名规范总结
- 首选:
TestDoStuff() - 使用包内测试时直接采用大写开头的测试函数名
- Go的测试框架不关心函数名是否与私有函数完全匹配,只要求以
Test开头
- 避免使用下划线:
Test_doStuff()不符合Go的命名惯例
- 不要使用小写:
TestdoStuff()可读性差
4. 示例:测试多个私有函数
// 被测试文件
package calculator
func add(a, b int) int {
return a + b
}
func multiply(a, b int) int {
return a * b
}
// 测试文件(相同包)
package calculator
import "testing"
func TestAdd(t *testing.T) {
result := add(2, 3)
if result != 5 {
t.Errorf("add(2, 3) = %d, want 5", result)
}
}
func TestMultiply(t *testing.T) {
result := multiply(2, 3)
if result != 6 {
t.Errorf("multiply(2, 3) = %d, want 6", result)
}
}
结论:使用包内测试并命名为TestDoStuff()是测试私有函数的标准做法。这种方式既保持了代码的可测试性,又遵循了Go的命名约定。