英文:
Is there a way to mock ValidationErrors in golang?
问题
我有一个函数,它解析类型为ValidationError的数组中的不同字段,以生成自定义错误消息,类似于以下函数。
func foo(err validator.ValidationErrors) []string {
var errStr []string
for _, e := range err {
tag := e.Tag()
field := e.Field()
errStr = append(errStr, tag + ":" + field)
}
return errStr
}
我想为这个函数编写单元测试,以确保自定义消息符合预期。我该如何模拟一个类型为validator.ValidationError的变量?下面是ValidationError的结构:
type ValidationErrors []FieldError
FieldError是一个包含函数(例如Tag()、Field()等)以获取错误详细信息的接口。
英文:
I have a function that parses different fields in the array of type ValidationError to generate custom error messages something like the following function.
func foo(err validator.ValidationErrors) []string {
var errStr []string
for _, e := range err {
tag := e.Tag()
field := e.Field()
errStr = append(errStr, tag + ":" + field)
}
return errStr
}
I want to write unit test for this function to ensure that the custom message is as expected. How can I mock a variable of type validator.ValidationError. Below is the structure of ValidationError:
type ValidationErrors []FieldError
FieldError is an interface which contains functions (such as Tag(), Field(), etc.) to get error details.
答案1
得分: 1
如果你想对一个接受validator.ValidationErrors参数的函数进行单元测试,可以自己构造测试值,使用一个实现了FieldError接口的类型(可能是一个结构体)。
方法并不多,但如果你只想实现函数调用所需的方法,你可以在结构体类型中嵌入validator.FieldError:
type mockFieldError struct {
validator.FieldError
tag string
field string
}
func (e mockFieldError) Tag() string { return e.tag }
func (e mockFieldError) Field() string { return e.field }
然后构造validator.ValidationErrors(注意,嵌入的validator.FieldError是未初始化的,所以确保被测试的函数不会调用你没有实现的其他方法,否则会引发 panic):
ve := validator.ValidationErrors{
mockFieldError{tag: "a", field: "field1"},
mockFieldError{tag: "b", field: "field2"},
}
现在,使用上述值调用foo函数会编译通过,并返回一个字符串,你可以与预期输出进行断言:
s := foo(ve)
fmt.Println(s) // [a:field1 b:field2]
完整的 playground 示例:https://go.dev/play/p/-btZ6lrKk4V
英文:
If you want to unit-test a function that takes validator.ValidationErrors, just construct the test value yourself, using a type (possibly a struct) that implements FieldError.
The methods are not many, but if you want to implement only those that your function calls, you can embed validator.FieldError in the struct type:
type mockFieldError struct {
validator.FieldError
tag string
field string
}
func (e mockFieldError) Tag() string { return e.tag }
func (e mockFieldError) Field() string { return e.field }
And construct validator.ValidationErrors (note that the embedded validator.FieldError is uninitialized, so make sure the function under test doesn't call other methods you didn't implement, or it will panic):
ve := validator.ValidationErrors{
mockFieldError{tag: "a", field: "field1"},
mockFieldError{tag: "b", field: "field2"},
}
So now calling foo with the above value compiles and returns a string that you can assert against your expected output:
s := foo(ve)
fmt.Println(s) // [a:field1 b:field2]
Full playground: https://go.dev/play/p/-btZ6lrKk4V
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论