将函数传递给辅助方法

时间:2020-01-15 08:25:24

标签: function loops go

在Go中可以迭代一组功能吗?

我的单元测试文件中有此辅助方法:

d=abs(x2-x1)+abs(y2-y1)

而不是复制/粘贴一行并像这样丑陋地更改第二个游乐者:

func helper(t *testing.T, f func(string) bool, stringArray []string, expected bool) {
    for _, input := range stringArray {
        if f(input) != expected {
            t.Errorf("Expected '%v' for string: %v", !expected, input)
        }

    }
}

我想知道这里是否有for选项将其简化为4行主体函数

func Test_isUnique(t *testing.T) {
    var valid = []string{"", "b", "ab", "acd", "asdfjkl", "aA"}
    var invalid = []string{"aa", "avva", "aaa", "asdfweryhfda", "asdfjkal"}
    helper(t, funcA, valid, true)
    helper(t, funcB, invalid, false)
    helper(t, funcC, valid, true)
    helper(t, funcD, invalid, false)
    helper(t, funcE, valid, true)
    helper(t, funcF, invalid, false)
    helper(t, funcG, valid, true)
    helper(t, funcH, invalid, false)
}

请原谅python / go的混合:)

2 个答案:

答案 0 :(得分:1)

是的,有可能。例如。您可以覆盖任何切片,包括那些元素类型为函数类型的切片。只需将您的函数切成薄片:

fs := []func(string) bool{funcA, funcB, funcC, funcD, ...}

for _, f := range fs {
    helper(t, f, valid, true)
    helper(t, f, invalid, false)
}

对于您要达到的目标,表驱动测试可能更适合。请同时检查Go Wiki: Table Driven TestsThe Go Blog: Using Subtests and Sub-benchmarks

答案 1 :(得分:1)

惯用的方法是使用表驱动测试:

func TestMyFunction(t *testing.T) {
  valid := []string{"", "b", "ab", "acd", "asdfjkl", "aA"}
  cases := []struct{
    name string,
    f func(string) bool
    input []string
    expected bool
  }{
    {
       "Test func a",
       funcA,
       valid,
       true
    },
    // Other test cases
  }

  for _, tc := range cases {
      t.Run(tc.name, func(t *testing.T) {
          helper(t, tc.func, tc.input, tc.expected)
      })
  }
}

作为旁注:实际上,您可以使用Helper函数显式标记辅助函数。这样可以确保您的助手功能不会在运行测试时从打印的行信息中排除:

func helper(t *testing.T) {
  t.Helper()
  // Helper function code
}