现在Go 1.18已经发布了对泛型的支持,为你的测试断言创建辅助函数比以前更容易了。
为你的测试断言使用辅助函数可以帮助:
- 使你的测试函数干净、清晰。
- 保持测试失败信息的一致性。
- 减少代码中因错别字而产生的错误的可能性。
为了说明这一点,我们假设你有一个简单的greet() ,你想测试的函数:
package main
import "fmt"
func greet(name string) (string, int) {
greeting := fmt.Sprintf("Hello %s", name)
// Return the greeting and its length (in bytes).
return greeting, len(greeting)
}
在过去,你对greet() 函数的测试可能会是这样的:
package main
import "testing"
func TestGreet(t *testing.T) {
greeting, greetingLength := greet("Alice")
// Test assertion to check the returned greeting string.
if greeting != "Hello Alice" {
t.Errorf("want: %s; got: %s", "Hello Alice", greeting)
}
// Test assertion to check the returned greeting length.
if greetingLength != 11 {
t.Errorf("want: %d; got: %d", 11, greetingLength)
}
}
在Go 1.18中,我们可以使用泛型和 comparable约束来创建一个Equal() 辅助函数,执行我们的测试断言。就个人而言,我喜欢把它放在一个可重复使用的assert 包中。
像这样:
package assert
import "testing"
func Equal[T comparable](t *testing.T, expected, actual T) {
t.Helper()
if expected != actual {
t.Errorf("want: %v; got: %v", expected, actual)
}
}
注意:这个 t.Helper()函数向 Go 测试运行器表明我们的Equal() 函数是一个测试助手。这意味着当t.Errorf() 被我们的Equal() 函数调用时,Go测试运行器将在输出中报告调用我们Equal() 函数的代码的文件名和行号。
有了这些,TestGreet() 的测试就可以简化成这样:
package main
import (
"testing"
"your.module.path/assert" // Import your assert package.
)
func TestGreet(t *testing.T) {
greeting, greetingLength := greet("Alice")
assert.Equal(t, "Hello Alice", greeting)
assert.Equal(t, 11, greetingLength)
}