Is there a way to mock ValidationErrors in golang?

Issue

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.

Solution

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

Answered By – blackgreen

Answer Checked By – Clifford M. (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.