我想通过使用一个用于测试输入的结构和另一个用于测试复杂测试所需输出的结构来缩短我的测试代码。我有这样的测试代码,它可以工作: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 关注
- 126 浏览
添加回答
举报
0/150
提交
取消