英文:
How to define a validator.Fieldlevel equivalent of a given string variable in Go?
问题
我正在使用Go的validator包验证我的配置文件。
我从配置文件中读取一个字段(createTime
),将其作为string
类型,并希望确保它是一个有效的时间duration
:
type Config struct{
...
CreateTime string `yaml:"createTime" validate:"duration,required"`
...
}
因此,我编写了一个自定义验证函数如下:
import (
"time"
"github.com/go-playground/validator/v10"
)
// isValidDuration是一个自定义验证函数,它将检查给定的字符串是否是一个有效的时间持续时间
func isValidDuration(fl validator.FieldLevel) bool {
if _, err := time.ParseDuration(fl.Field().String()); err != nil {
return false
}
return true
}
我将其用于验证如下:
func (configObject *Config) Validate() error {
// 验证配置
validate := validator.New()
if err := validate.RegisterValidation("duration", isValidDuration); err != nil {
return err
}
return validate.Struct(configObject)
}
自定义验证器正常工作,我想为isValidDuration
函数编写一个单元测试。以下是IDE生成的单元测试样板代码:
import (
"testing"
"github.com/go-playground/validator/v10"
)
func Test_isValidDuration(t *testing.T) {
type args struct {
fl validator.FieldLevel
}
var tests = []struct {
name string
args args
want bool
}{
// TODO: 添加测试用例。
{name: "positive", args: ???????, want: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := isValidDuration(tt.args.fl); got != tt.want {
t.Errorf("isValidDuration() = %v, want %v", got, tt.want)
}
})
}
}
我是Go的新手,不确定如何在上述测试用例的args
字段中传递参数。如何创建一个包含一个validator.FieldLevel
字段的结构体?
理想情况下,我想传递类似于"10m"
的内容作为args
,并且由于它是一个有效的时间持续时间,我期望isValidDuration
的输出为true
,因为"10m"
是一个有效的持续时间。我尝试了这个:{name: "positive", args: struct{ fl validator.FieldLevel }{fl: "10m"}, want: true}
,但是得到了这个错误:'"10m"'(类型为string)无法表示为类型validator.FieldLevel
。
如何创建一个值等于"10m"
的validator.FieldLevel
变量?有人可以帮帮我吗?
英文:
I'm validating my config file using Go's validator package
One of the fields(createTime
) from the config file I'm reading as a string
, and want to make sure that it is a valid time duration
:
type Config struct{
...
CreateTime string `yaml:"createTime" validate:"duration,required"`
...
}
So, I have written a custom validation function as follows:
import (
"time"
"github.com/go-playground/validator/v10"
)
// isValidDuration is a custom validation function, and it will check if the given string is a valid time duration
func isValidDuration(fl validator.FieldLevel) bool {
if _, err := time.ParseDuration(fl.Field().String()); err != nil {
return false
}
return true
}
Which I'm using for validation as follows:
func (configObject *Config) Validate() error {
// Validate configurations
validate := validator.New()
if err := validate.RegisterValidation("duration", isValidDuration); err != nil {
return err
}
return validate.Struct(configObject)
}
The custom validator is working fine and I want to write a unit test for isValidDuration
function. Following is the unit test boilerplate generated by IDE:
import (
"testing"
"github.com/go-playground/validator/v10"
)
func Test_isValidDuration(t *testing.T) {
type args struct {
fl validator.FieldLevel
}
var tests = []struct {
name string
args args
want bool
}{
// TODO: Add test cases.
{name: "positive", args: ???????, want: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := isValidDuration(tt.args.fl); got != tt.want {
t.Errorf("isValidDuration() = %v, want %v", got, tt.want)
}
})
}
}
I'm new to Go and not sure what to pass in the args
field of the testcase above. How do I create a struct
containing one validator.FieldLevel
field?
Ideally, I would like to pass something like "10m"
as args
and since it is a valid time duration, would expect the output of isValidDuration
as true
since "10m"
is a valid duration.
I'm trying this: {name: "positive", args: struct{ fl validator.FieldLevel }{fl: "10m"}, want: true}
but getting this ereor: '"10m"' (type string) cannot be represented by the type validator.FieldLevel
How do I create a validator.FieldLevel
variable with value equivalent to "10m"
? Could someone please help me out?
答案1
得分: 1
问题1
一个语义问题,fl不是String类型。
{
name: "positive",
args: args{
fl: validator.FieldLevel{
// ....
},
},
want: true,
},
问题2
如何使用validator.FieldLevel
。
在代码库中,我们可以看到FieldLevel是一个接口,你需要创建一个未导出的、不应该被用户使用的结构体validate
。
type FieldLevel interface
// ...
var _ FieldLevel = new(validate)
回答
所以,最好像validator包的UT一样编写你的UT。不要使用IDE中的代码!
// 看一下这个UT
// github.com/go-playground/validator/v10@v10.10.0/validator_test.go
func TestKeysCustomValidation(t *testing.T) {
英文:
problem1
A language semantic problem, fl is not the type String.
{
name: "positive",
args: args{
fl: validator.FieldLevel{
// ....
},
},
want: true,
},
problem2
How to use validator.FieldLevel
.
In code base, we can see FieldLevel is a interface, and you need create struct validate
, which is not exported and not supposed to be used by user.
type FieldLevel interface
// ...
var _ FieldLevel = new(validate)
answer
So, you'd best to write your UT like UT of validator package. Don't use the code from your IDE!
// have a look at this UT
// github.com/go-playground/validator/v10@v10.10.0/validator_test.go
func TestKeysCustomValidation(t *testing.T) {
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论