慕田峪7331174
2022-07-11 15:06:42
我想通過使用一個用于測試輸入的結構和另一個用于測試復雜測試所需輸出的結構來縮短我的測試代碼。我有這樣的測試代碼,它可以工作:func TestMyTest(*testing.T) { type Test struct { n int items map[string][]int order int expect []string } tests := []Test{ { n: 3, items: map[string][]int{ "item1": []int{1, 2}, "item2": []int{3, 4}, "item3": []int{5, 6}, }, order: 1, expect: []string{"item1"}, }, // ... more test cases } for testNo, test := range tests { output := myTest(test.n, test.items, test.order) desire := test.expect fmt.Printf("Test %v ", testNo+1) if reflect.DeepEqual(output, desire) { fmt.Println("PASS") } else { fmt.Println("FAIL") } fmt.Println("Got:", output, "Expected:", desire) }}我的虛擬功能:func myTest(n int, items map[string][]int, order int) []string { res := []string{"item1"} return res}但是,如果我有更復雜的輸入和輸出,我不想輸入所有參數,而是想將它們分組到 1 個結構中,如下所示:func TestMyTest2(*testing.T) { type TestInput struct { n int items map[string][]int order int } type TestExpect struct { expect []string } type Test struct { input TestInput expect TestExpect } tests := []Test{ { input: TestInput{ n: 3, items: map[string][]int{ "item1": []int{10, 15}, "item2": []int{3, 4}, "item3": []int{17, 8}, }, order: 1, }, expect: TestExpect{ []string{"item3"}, }, },我遇到的錯誤:have (TestInput) want (int, map[string][]int, int)這是有道理的,但我一直在努力“傳播”我的 TestInput 中的值以傳遞我的函數。我想做的就像在 JS 中一樣,我可以做...params“傳播”或在 Python**params中“解包”。我已經在這里、這里、這里和這里查看了答案,但仍然無法弄清楚這一點。
1 回答

LEATH
TA貢獻1936條經驗 獲得超7個贊
使用反射包傳播參數:
func spread(fn interface{}, args interface{}) interface{} {
var in []reflect.Value
s := reflect.Indirect(reflect.ValueOf(args))
for i := 0; i < s.NumField(); i++ {
in = append(in, s.Field(i))
}
out := reflect.ValueOf(fn).Call(in)
return out[0].Interface()
}
TestInput必須導出其中的字段才能使其正常工作。
以下是如何使用它:
for i, test := range tests {
output := spread(myTest, test.input)
desire := test.expect.expect
if !reflect.DeepEqual(output, desire) {
t.Errorf("%d: got %v, want %v", i, output, desire)
}
}
我認為寫出論點比使用反射技巧更簡單。寫出參數的代碼比反射代碼快,但這對于測試可能無關緊要。
- 1 回答
- 0 關注
- 125 瀏覽
添加回答
舉報
0/150
提交
取消