我想要一个单元测试来验证特定命令行标志是否在枚举中。
以下是我想编写测试的代码:
var formatType string
const (
text = "text"
json = "json"
hash = "hash"
)
func init() {
const (
defaultFormat = "text"
formatUsage = "desired output format"
)
flag.StringVar(&formatType, "format", defaultFormat, formatUsage)
flag.StringVar(&formatType, "f", defaultFormat, formatUsage+" (shorthand)")
}
func main() {
flag.Parse()
}
只有当-format等于上面给出的一个const值时,才会传递所需的测试。此值可在formatType中使用。一个正确的调用示例是:program -format text
测试所需行为的最佳方法是什么?
注意:也许我的措辞很差,但显示的代码不是单元测试本身,而是我想编写单元测试的代码。这是我正在撰写的工具中的一个简单示例,并且想要询问是否有一种测试工具有效输入的好方法。
答案 0 :(得分:10)
使用flag.Var
包中的flag
功能可以实现标志的自定义测试和处理。
Flag.Var “定义具有指定名称和用法字符串的标志。标志的类型和值由第一个参数表示,类型为Value,它通常包含用户定义的Value实现。 “
flag.Value
是满足Value
接口的任何类型,定义为:
type Value interface {
String() string
Set(string) error
}
中的flag
package source文件中有一个很好的示例
对于您的用例,您可以使用以下内容:
package main
import (
"errors"
"flag"
"fmt"
)
type formatType string
func (f *formatType) String() string {
return fmt.Sprint(*f)
}
func (f *formatType) Set(value string) error {
if len(*f) > 0 && *f != "text" {
return errors.New("format flag already set")
}
if value != "text" && value != "json" && value != "hash" {
return errors.New("Invalid Format Type")
}
*f = formatType(value)
return nil
}
var typeFlag formatType
func init() {
typeFlag = "text"
usage := `Format type. Must be "text", "json" or "hash". Defaults to "text".`
flag.Var(&typeFlag, "format", usage)
flag.Var(&typeFlag, "f", usage+" (shorthand)")
}
func main() {
flag.Parse()
fmt.Println("Format type is", typeFlag)
}
这对于这样一个简单的例子来说可能有些过分,但在定义更复杂的标志类型时可能非常有用(链接的示例将逗号分隔的间隔列表转换为基于time.Duration
的自定义类型的片段)
编辑:在回答如何针对标志运行单元测试时,最典型的例子是flag_test.go
in the flag package source。与测试自定义标志变量相关的部分从Line 181开始。
答案 1 :(得分:0)
我不确定我们是否同意“单元测试”一词。你想要实现的目标在我看来 更像是一个程序中非常正常的测试。你可能想做这样的事情:
func main() {
flag.Parse()
if formatType != text || formatType != json || formatType != hash {
flag.Usage()
return
}
// ...
}
遗憾的是,用自己的值验证器扩展标记Parser是不容易的
所以你现在必须坚持这一点。
请参阅Intermernet以获取定义自定义格式类型及其验证器的解决方案。