Unit test values ​​of different flags

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 would like to unit test what happens here when the user provides different values ​​for the config argument (the name of the configuration file is used else where).
Is there a way to tell the flag package to pass different values ​​for the config argument during testing?

+4
source share
2 answers

, , , , -h, . , , :

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())
        }
    }

}

: https://play.golang.org/p/h1nok1UMLA , .

+1

, go test , go test -config testconfig . , flag.Parse() init(), ( https://groups.google.com/d/msg/golang-nuts/uSFM8jG7yn4/PIQfEWOZx4EJ).

package main

import (
    "flag"
    "testing"
)

var configFile = flag.String("config", "", "File containing configuration")

func getConfigFile() string {
    return *configFile
}

func TestConfig(t *testing.T) {
    want := "testconfig"
    if s := getConfigFile(); s != want {
        t.Errorf("Got %s, want %s", s, want)
    }
}

:

$ go test
--- FAIL: TestConfig (0.00s)
    flag_test.go:17: Got , want testconfig
FAIL
exit status 1
FAIL    github.com/dmitris/soflagtest   0.013s
$ go test -config testconfig
PASS
ok      github.com/dmitris/soflagtest   0.012s

var configFile string init() :

func init() {
     flag.StringVar(&configFile, "config", "", "File containing configuration")
}

( getConfigFile, configFile )

0

Source: https://habr.com/ru/post/1649845/


All Articles