3

I have a library in which there are both Client and MockClient structs which both implement the same ClientInterface interface. I would like to write unit tests to keep these structs in sync so that they not only just implement the interface, but so that MockClient has all of Client's methods. To this end, I would like to get a list of a struct's methods in order to print an informative error message if one of the methods of Client is missing from MockClient.

I've tried adapting How to get the name of a function in Go? to this simplified example:

package main

import (
    "fmt"
    "reflect"
    "runtime"
)

type Person struct {
    Name string
}

func (person *Person) GetName() string {
    return person.Name
}

func main() {
    person := Person{Name: "John Doe"}
    personValue := reflect.ValueOf(&person)

    for i := 0; i < personValue.NumMethod(); i++ {
        fmt.Println(runtime.FuncForPC(personValue.Method(i).Pointer()).Name())
    }
}

What I would like is for this script (shared at https://play.golang.org/p/HwvhEPfWI5I) to print GetName. However, instead, it prints

reflect.methodValueCall

How can I get this script to print the names of *Person's methods?

Kurt Peek
  • 52,165
  • 91
  • 301
  • 526
  • 1
    Note that there's a compile-time test for "type *T or T implements interface I": `var _ I = (*T)(nil)` or `var _ I = T{}` (depending on whether you're testing `T` itself, or `*T`). See https://stackoverflow.com/q/10498547/1256452 for details. That's not the same as listing the methods of the struct, of course; its usefulness is when you have defined an interface, and want to make sure that each implementation you wrote, implements that interface. – torek Jan 20 '20 at 23:28

1 Answers1

6

Use the type to get the method names:

t := reflect.TypeOf(&person)
for i := 0; i < t.NumMethod(); i++ {
    m := t.Method(i)
    fmt.Println(m.Name)
}

Run it on the playground.