在 Go 1.18 中,程序员可以利用其新的泛型功能。在探索这一新功能时,开发人员在执行表测试时可能会遇到挑战。本次讨论探讨了这样一个挑战,特别是在使用表数据测试泛型函数的情况下。
在表测试期间尝试使用不同类型的参数实例化泛型函数时会出现此问题。为了解决这个问题,开发人员通常会重新声明每个函数的测试逻辑,如以下代码片段所示:
package main import ( "testing" "github.com/stretchr/testify/assert" ) type Item interface { int | string } type store[T Item] map[int64]T // add adds an Item to the map if the id of the Item isn't present already func (s store[T]) add(key int64, val T) { _, exists := s[key] if exists { return } s[key] = val } func TestStore(t *testing.T) { t.Run("ints", testInt) t.Run("strings", testString) } type testCase[T Item] struct { name string start store[T] key int64 val T expected store[T] } func testString(t *testing.T) { t.Parallel() tests := []testCase[string]{ { name: "empty map", start: store[string]{}, key: 123, val: "test", expected: store[string]{ 123: "test", }, }, { name: "existing key", start: store[string]{ 123: "test", }, key: 123, val: "newVal", expected: store[string]{ 123: "test", }, }, } for _, tc := range tests { t.Run(tc.name, runTestCase(tc)) } } func testInt(t *testing.T) { t.Parallel() tests := []testCase[int]{ { name: "empty map", start: store[int]{}, key: 123, val: 456, expected: store[int]{ 123: 456, }, }, { name: "existing key", start: store[int]{ 123: 456, }, key: 123, val: 999, expected: store[int]{ 123: 456, }, }, } for _, tc := range tests { t.Run(tc.name, runTestCase(tc)) } } func runTestCase[T Item](tc testCase[T]) func(t *testing.T) { return func(t *testing.T) { tc.start.add(tc.key, tc.val) assert.Equal(t, tc.start, tc.expected) } }
但是,这种方法需要为每个函数提供冗余的测试逻辑。泛型类型的本质在于它们能够处理任意类型,并且约束确保这些类型支持相同的操作。
与其过度测试不同的类型,更谨慎的做法是只专注于测试这些类型使用运算符时表现出不同的行为。例如,“ ”运算符对于数字(求和)和字符串(连接)具有不同的含义,或者“”运算符对数字(更大/更小)和字符串(字典顺序)有不同的解释。
为了进一步说明此问题,开发人员应参考用户尝试使用泛型函数执行表测试的类似讨论。
以上是我们如何有效地对具有不同类型参数的泛型函数进行表测试?的详细内容。更多信息请关注PHP中文网其他相关文章!