首页 > 解决方案 > 如何测试 CLI 标志 - 当前因“重新定义标志”而失败

问题描述

我有以下要测试的功能:

import (
    "github.com/spf13/pflag"
)

func parseCLIFlags() cliOptions {
    mode := pflag.StringP("mode", "m", "json", "file format")
    outType := pflag.StringP("out-type", "o", "stdout", "Output format")
    outFile := pflag.String("out-file", "", "Output file. Only used if `--out-type` is not stdout")
    inFiles := pflag.StringArrayP("file", "f", []string{}, "Files to compare. Use this flag multiple times, once for each file.")

    pflag.Parse()

    options := cliOptions{
        mode:    *mode,
        outType: *outType,
        outFile: *outFile,
        inFiles: *inFiles,
    }
    return options
}

我正在尝试使用以下测试进行测试:

func TestFlagsAreParsedCorrectly(t *testing.T) {
    os.Args = []string{"schmp", "-f", "testdata/yaml/yaml_1.yaml", "--file", "testdata/yaml/yaml_2.yaml", "--mode", "yaml", "-o", "json", "--out-file", "sample.json"}
    cliOptions := parseCLIFlags()
    if cliOptions.mode != "yaml" {
        t.Fatalf("could not set mode")
    }
    if cliOptions.outType != "json" {
        t.Fatalf("could not set outType")
    }
    if cliOptions.outFile != "sample.json" {
        t.Fatalf("could not set outFile")
    }
    if !reflect.DeepEqual(cliOptions.inFiles, []string{"testdata/yaml/yaml_1.yaml", "testdata/yaml/yaml_2.yaml"}) {
        fmt.Println("could not set inFiles")
    }
}

func TestCheckDefaultFlags(t *testing.T) {
    os.Args = []string{"schmp"}
    cliOptions := parseCLIFlags()
    if cliOptions.mode != "json" {
        t.Fatalf("default mode is not `json`")
    }
}

但是我的测试很恐慌flag redefined: mode

知道如何解决此问题以便进行测试吗?

标签: unit-testinggotesting

解决方案


根据@Adrian 的评论,我可以通过创建一个FlagSetin来修复它parseCLIFlags

func parseCLIFlags() cliOptions {
    flag := pflag.FlagSet{}
    mode := flag.StringP("mode", "m", "json", "file format")
    outType := flag.StringP("out-type", "o", "stdout", "Output format")
    outFile := flag.String("out-file", "", "Output file. Only used if `--out-type` is not stdout")
    inFiles := flag.StringArrayP("file", "f", []string{}, "Files to compare. Use this flag multiple times, once for each file.")
    flag.Parse(os.Args[1:])

    options := cliOptions{
        mode:    *mode,
        outType: *outType,
        outFile: *outFile,
        inFiles: *inFiles,
    }
    return options
}

推荐阅读