mirror of https://github.com/grpc/grpc-go.git
grpctest: use an interface instead of reflection (#6553)
This commit is contained in:
parent
cc705fe472
commit
7d3996fd85
|
@ -62,6 +62,12 @@ func (Tester) Teardown(t *testing.T) {
|
|||
TLogger.EndTest(t)
|
||||
}
|
||||
|
||||
// Interface defines Tester's methods for use in this package.
|
||||
type Interface interface {
|
||||
Setup(*testing.T)
|
||||
Teardown(*testing.T)
|
||||
}
|
||||
|
||||
func getTestFunc(t *testing.T, xv reflect.Value, name string) func(*testing.T) {
|
||||
if m := xv.MethodByName(name); m.IsValid() {
|
||||
if f, ok := m.Interface().(func(*testing.T)); ok {
|
||||
|
@ -74,9 +80,8 @@ func getTestFunc(t *testing.T, xv reflect.Value, name string) func(*testing.T) {
|
|||
}
|
||||
|
||||
// RunSubTests runs all "Test___" functions that are methods of x as subtests
|
||||
// of the current test. If x contains methods "Setup(*testing.T)" or
|
||||
// "Teardown(*testing.T)", those are run before or after each of the test
|
||||
// functions, respectively.
|
||||
// of the current test. Setup is run before the test function and Teardown is
|
||||
// run after.
|
||||
//
|
||||
// For example usage, see example_test.go. Run it using:
|
||||
//
|
||||
|
@ -85,13 +90,10 @@ func getTestFunc(t *testing.T, xv reflect.Value, name string) func(*testing.T) {
|
|||
// To run a specific test/subtest:
|
||||
//
|
||||
// $ go test -v -run 'TestExample/^Something$' .
|
||||
func RunSubTests(t *testing.T, x any) {
|
||||
func RunSubTests(t *testing.T, x Interface) {
|
||||
xt := reflect.TypeOf(x)
|
||||
xv := reflect.ValueOf(x)
|
||||
|
||||
setup := getTestFunc(t, xv, "Setup")
|
||||
teardown := getTestFunc(t, xv, "Teardown")
|
||||
|
||||
for i := 0; i < xt.NumMethod(); i++ {
|
||||
methodName := xt.Method(i).Name
|
||||
if !strings.HasPrefix(methodName, "Test") {
|
||||
|
@ -104,8 +106,8 @@ func RunSubTests(t *testing.T, x any) {
|
|||
//
|
||||
// Note that a defer would run before t.Cleanup, so if a goroutine
|
||||
// is closed by a test's t.Cleanup, a deferred leakcheck would fail.
|
||||
t.Cleanup(func() { teardown(t) })
|
||||
setup(t)
|
||||
t.Cleanup(func() { x.Teardown(t) })
|
||||
x.Setup(t)
|
||||
tfunc(t)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -44,20 +44,3 @@ func TestRunSubTests(t *testing.T) {
|
|||
t.Fatalf("x = %v; want all fields true", x)
|
||||
}
|
||||
}
|
||||
|
||||
type tNoST struct {
|
||||
test bool
|
||||
}
|
||||
|
||||
func (t *tNoST) TestSubTest(*testing.T) {
|
||||
t.test = true
|
||||
}
|
||||
|
||||
func TestNoSetupOrTeardown(t *testing.T) {
|
||||
// Ensures nothing panics or fails if Setup/Teardown are omitted.
|
||||
x := &tNoST{}
|
||||
RunSubTests(t, x)
|
||||
if want := (&tNoST{test: true}); !reflect.DeepEqual(x, want) {
|
||||
t.Fatalf("x = %v; want %v", x, want)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue