一旦我理解了一切都必须使用或返回Value类型,这就是我的想法。
诀窍是使用:
ValueOf
为了获得接收者的价值Value.MethodByName
寻找那个接收者 价值 的函数 __Value.IsNil
测试nil
返回值。
测试代码的主要摘录:
var funcNames = []string{"Func1", "Func2", "Func3"}func TestFunc(t *testing.T) { stype := reflect.ValueOf(s) for _, fname := range funcNames { fmt.Println(fname) sfunc := stype.MethodByName(fname) // no parameter => empty slice of Value ret := sfunc.Call([]reflect.Value{}) val := ret[0].Int() // That would panic for a nil returned err // err := ret[1].Interface().(error) err := ret[1] if val < 1 { t.Error(fname + " should return positive value") } if err.IsNil() == false { t.Error(fname + " shouldn't err") } }}在去操场上看到一个可运行的示例。
请注意,如果使用不存在的函数名称来调用该测试函数,则将出现恐慌。在这里
看到那个例子。
runtime.panic(0x126660, 0x10533140) /tmp/sandbox/go/src/pkg/runtime/panic.c:266 +0xe0testing.func·005() /tmp/sandbox/go/src/pkg/testing/testing.go:383 +0x180----- stack segment boundary -----runtime.panic(0x126660, 0x10533140) /tmp/sandbox/go/src/pkg/runtime/panic.c:248 +0x160reflect.flag.mustBe(0x0, 0x13) /tmp/sandbox/go/src/pkg/reflect/value.go:249 +0xc0reflect.Value.Call(0x0, 0x0, 0x0, 0xfeef9f28, 0x0, ...) /tmp/sandbox/go/src/pkg/reflect/value.go:351 +0x40main.TestFunc(0x10546120, 0xe) /tmpfs/gosandbox-3642d986_9569fcc1_f443bbfb_73e4528d_c874f1af/prog.go:34 +0x240
去操场从那恐慌中恢复,但您的测试程序可能不会。
这就是为什么我添加到上面的测试功能:
for _, fname := range funcNames { defer func() { if x := recover(); x != nil { t.Error("TestFunc paniced for", fname, ": ", x) } }() fmt.Println(fname)产生(参见示例)更好的输出:
Func1Func2Func3Func4--- FAIL: TestFunc (0.00 seconds) prog.go:48: Func2 should return positive value prog.go:51: Func3 shouldn't err prog.go:32: TestFunc paniced for Func4 : reflect: call of reflect.Value.Call on zero ValueFAIL



