I have the following Golang code:
func getConfigFile() string {
var configFile string
flag.StringVar(&configFile, "config", "", "File containing configuration")
flag.Parse()
return configFile
}
This function is used elsewhere in my code, and I'd like to unit test what happens here when the user provides different values for the config argument (the config file name is used else where).
Is there a way to tell the flag package to return different values for the config argument while under test?
I have found that for testing custom flags is better to create a custom flag set, in that way I can fully test the flags, including the -h
option without exiting the tests. hope the attached code could give you and idea of how you could implement test on your code:
package main
import (
"flag"
"fmt"
"os"
"reflect"
"testing"
)
// Test Helper
func expect(t *testing.T, a interface{}, b interface{}) {
if a != b {
t.Errorf("Expected: %v (type %v) Got: %v (type %v)", a, reflect.TypeOf(a), b, reflect.TypeOf(b))
}
}
type Flags struct {
ConfigFile string
}
func (self *Flags) Parse(fs *flag.FlagSet) (*Flags, error) {
fs.StringVar(&self.ConfigFile, "config", "", "File containing configuration")
err := fs.Parse(os.Args[1:])
if err != nil {
return nil, err
}
return self, nil
}
func main() {
fs := flag.NewFlagSet("test", flag.ContinueOnError)
parser := Flags{}
flags, err := parser.Parse(fs)
if err != nil {
panic(err)
}
fmt.Println(flags)
}
func TestFlags(t *testing.T) {
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
var flagTest = []struct {
flag []string
name string
expected interface{}
}{
{[]string{"cmd", "-config", "config.yaml"}, "ConfigFile", "config.yaml"},
{[]string{"cmd", "-config", "config.json"}, "ConfigFile", "config.json"},
{[]string{"cmd", "-v"}, "Version", true},
}
for _, f := range flagTest {
os.Args = f.flag
p := &Flags{}
fs := flag.NewFlagSet("test", flag.ContinueOnError)
flags, err := p.Parse(fs)
if err != nil {
t.Error(err)
}
refValue := reflect.ValueOf(flags).Elem().FieldByName(f.name)
switch refValue.Kind() {
case reflect.Bool:
expect(t, f.expected, refValue.Bool())
case reflect.String:
expect(t, f.expected, refValue.String())
}
}
}
I put it also here: https://play.golang.org/p/h1nok1UMLA hope it can give you an idea.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With