我有一个go函数,它使用flag包来解析命令行参数。我想为参数和值的各种组合编写单元测试,但我遇到了这个问题。我可以运行任何一个测试来测试函数,但当我运行一组测试时,我在第二次调用函数时得到一个错误:“flag redefined”。
有没有办法重置flag包,这样当我用相同的arg名称第二次调用flag.StringVar()时,就不会出现“flag redefined”错误了?
编辑:我正在添加一个演示错误的代码示例。(这不是真实的代码结构.在真实的代码中,功能分布在生产代码、单元测试函数和重置函数中。)
func broken() {
var debug bool
flag.BoolVar(&debug, "debug", false, "enable debug")
flag.Parse()
flag.CommandLine.VisitAll(func(f *flag.Flag) {
if f.Value != nil {
f.Value.Set(f.DefValue)
}
})
// Error occurs here when BoolVar is called with the
// same "debug" string.
flag.BoolVar(&debug, "debug", false, "enable debug")
flag.Parse()
}
字符串
实际上,代码看起来像这样:
type cmdArgs struct {
debug bool,
file string,
}
func main() {
args, err := parseArgs()
if err != nil {
// bail!!
}
}
func parseArgs() (cmdArgs, error) {
var debug bool
var file string
flag.BoolVar(&debug, "debug", false, "enable debug")
flag.StringVar(&file, "file", "", "input file")
flag.Parse()
if "" == file {
return cmdArgs{}, errors.New("--file is required.")
}
return cmdArgs{
debug: debug,
file: file,
}, nil
}
型
单元测试看起来像这样:
func TestParseArgs_noFileArg(t *testing.T) {
resetArgs()
args, err := parseArgs()
assert.Error(t, err, "error expected, none returned--
file arg not provided, but required.")
}
func TestParseArgs_withFileArg(t *testing.T) {
resetArgs()
os.Args = append(os.Args, "-file")
os.Args = append(os.Args, "./input.json")
args, err := parseArgs()
assert.NoError(t, err, "Unexpected error")
assert.Equal(t, "input.json", args.file,
"args.file value was incorrect.")
}
func resetArgs() {
flag.CommandLine.VisitAll(func(f *flag.Flag) {
if f.Value != nil {
f.Value.Set(f.DefValue)
}
})
}
型
3条答案
按热度按时间nkoocmlb1#
定义标志一次,并在每次测试中重用。
选项1:使用包级变量。
字符串
选项2:使用闭包。
型
无法从标志集中清除标志定义。
roejwanj2#
在每个测试中将命令行标志设置为新设置。
字符串
7xzttuei3#
如果你想针对一组固定的标志定义测试不同的命令行参数,那么请执行以下操作:
编写一个函数来重置命令行标志并解析新标志:
字符串
定义标志一次,并在每次测试中重复使用:
型
https://go.dev/play/p/Y6uZD5JTyTs