【问题标题】:How to define a validator.Fieldlevel equivalent of a given string variable in Go?如何在 Go 中定义与给定字符串变量等效的 validator.Fieldlevel?
【发布时间】:2022-02-06 14:50:45
【问题描述】:

我正在使用 Go 的 validator package 验证我的配置文件

我正在读取的配置文件中的一个字段(createTime)为string,并希望确保它是有效时间duration

type Config struct{
    ...
    CreateTime   string `yaml:"createTime" validate:"duration,required"`
    ...
}

所以,我写了一个自定义验证函数如下:

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
}

我用于验证如下:

func (configObject *Config) Validate() error {

    // Validate configurations
    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: 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)
            }
        })
    }
}

我是 Go 新手,不知道在上面的测试用例的 args 字段中传递什么。如何创建一个包含一个 validator.FieldLevel 字段的 struct

理想情况下,我想将"10m" 之类的内容传递为args,并且由于它是有效的持续时间,因此预计isValidDuration 的输出为true,因为"10m" 是有效的持续时间。 我正在尝试这个:{name: "positive", args: struct{ fl validator.FieldLevel }{fl: "10m"}, want: true},但得到这个错误:'"10m"' (type string) cannot be represented by the type validator.FieldLevel

如何创建一个值等于"10m"validator.FieldLevel 变量?有人可以帮帮我吗?

【问题讨论】:

    标签: unit-testing validation go


    【解决方案1】:

    问题1

    一个语言语义问题,fl不是String类型。

    {
      name: "positive", 
      args: args{
        fl: validator.FieldLevel{
           // ....
        },
      }, 
      want: true,
    },
    

    问题2

    如何使用validator.FieldLevel

    在代码库中,我们可以看到FieldLevel是一个接口,你需要创建struct validate,它没有被导出,不应该被用户使用。

    type FieldLevel interface
    
    // ...
    
    var _ FieldLevel = new(validate)
    

    回答

    因此,您最好将您的 UT 编写为验证器包的 UT。不要使用 IDE 中的代码!

    // have a look at this UT
    // github.com/go-playground/validator/v10@v10.10.0/validator_test.go
    func TestKeysCustomValidation(t *testing.T) {
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-02
      • 2019-04-14
      • 2019-01-05
      • 2023-03-09
      • 2014-01-14
      • 1970-01-01
      • 1970-01-01
      • 2011-10-13
      相关资源
      最近更新 更多