猿问

扩展或解包结构作为测试的输入参数

我想通过使用一个用于测试输入的结构和另一个用于测试复杂测试所需输出的结构来缩短我的测试代码。


我有这样的测试代码,它可以工作:


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中“解包”。

我已经在这里这里这里这里查看了答案,但仍然无法弄清楚这一点。



慕田峪7331174
浏览 127回答 1
1回答

LEATH

使用反射包传播参数:func spread(fn interface{}, args interface{}) interface{} {&nbsp; &nbsp; var in []reflect.Value&nbsp; &nbsp; s := reflect.Indirect(reflect.ValueOf(args))&nbsp; &nbsp; for i := 0; i < s.NumField(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; in = append(in, s.Field(i))&nbsp; &nbsp; }&nbsp; &nbsp; out := reflect.ValueOf(fn).Call(in)&nbsp; &nbsp; return out[0].Interface()}TestInput必须导出其中的字段才能使其正常工作。以下是如何使用它:for i, test := range tests {&nbsp; &nbsp; output := spread(myTest, test.input)&nbsp; &nbsp; desire := test.expect.expect&nbsp; &nbsp; if !reflect.DeepEqual(output, desire) {&nbsp; &nbsp; &nbsp; &nbsp; t.Errorf("%d: got %v, want %v", i, output, desire)&nbsp; &nbsp; }}我认为写出论点比使用反射技巧更简单。写出参数的代码比反射代码快,但这对于测试可能无关紧要。
随时随地看视频慕课网APP

相关分类

Go
我要回答