title: How to test method with reflect?
body: <p>I have a method Sync() that overrides <code>Config</code> field's values that are set in the environment.
  The environment variable names are derived from config fields by underscoring, and uppercasing the name. E.g. AppName will have a corresponding environment variable APP_NAME</p>
  
  <p>Please help me to test the following cases. There are complex things like <a href="https://golang.org/pkg/reflect/#Value.Set" rel="nofollow">https://golang.org/pkg/reflect/#Value.Set</a>:      </p>
  
  <blockquote>
    <p>Set assigns x to the value v. It panics if CanSet returns false. As in
    Go, x's value must be assignable to v's type.</p>
  </blockquote>
  
  <p>So I don't know how to test this case?</p>
  
  <pre><code>import (
      "encoding/json"
      "errors"
      "fmt"
       "os"
      "path/filepath"
      "reflect"
      "strconv"
      "strings"
      "github.com/BurntSushi/toml"
      "github.com/fatih/camelcase"
      "gopkg.in/yaml.v2"
  )
  
  type Config struct {
      AppName   string 
      BaseURL   string 
      Port      int    
      Verbose   bool   
      StaticDir string 
      ViewsDir  string 
  }
  
  func (c *Config) Sync() error {
      cfg := reflect.ValueOf(c).Elem()
      cTyp := cfg.Type()
  
      for k := range make([]struct{}, cTyp.NumField()) {
          field := cTyp.Field(k)
  
          cm := getEnvName(field.Name)
          env := os.Getenv(cm)
          if env == "" {
              continue
          }
          switch field.Type.Kind() {
          case reflect.String:
              cfg.FieldByName(field.Name).SetString(env)
          case reflect.Int:
              v, err := strconv.Atoi(env)
              if err != nil {
                  return fmt.Errorf("loading config field %s %v", field.Name, err)
              }
              cfg.FieldByName(field.Name).Set(reflect.ValueOf(v))
          case reflect.Bool:
              b, err := strconv.ParseBool(env)
              if err != nil {
                  return fmt.Errorf("loading config field %s %v", field.Name, err)
              }
              cfg.FieldByName(field.Name).SetBool(b)
          }
  
      }
      return nil
  }
  </code></pre>