Writing unit tests for generic functions in golang

WBOY
Release: 2024-02-11 09:42:09
forward
933 people have browsed it

在 golang 中为泛型函数编写单元测试

php Editor Banana brings you an article about writing unit tests for generic functions in Golang. Golang is a strongly typed programming language, however, its support for generics is relatively weak. Therefore, writing unit tests for generic functions can present some challenges. This article will introduce you to how to effectively write unit tests for generic functions in Golang to ensure the quality and reliability of your code. Whether you are a beginner or an experienced developer, this article will provide you with practical tips and methods to help you easily deal with unit testing of generic functions. Let’s take a look!

Question content

I have this simple generic function that retrieves a key from a map

// getmapkeys returns the keys of a map
func getmapkeys[t comparable, u any](m map[t]u) []t {
    keys := make([]t, len(m))
    i := 0
    for k := range m {
        keys[i] = k
        i++
    }
    return keys
}
Copy after login

I'm trying to write a table-driven unit test for it, like this:

var testunitgetmapkeys = []struct {
    name     string
    inputmap interface{}
    expected interface{}
}{
    {
        name:     "string keys",
        inputmap: map[string]int{"foo": 1, "bar": 2, "baz": 3},
        expected: []string{"foo", "bar", "baz"},
    },
    {
        name:     "int keys",
        inputmap: map[int]string{1: "foo", 2: "bar", 3: "baz"},
        expected: []int{1, 2, 3},
    },
    {
        name:     "float64 keys",
        inputmap: map[float64]bool{1.0: true, 2.5: false, 3.1415: true},
        expected: []float64{1.0, 2.5, 3.1415},
    },
}
Copy after login

However, the following code fails

func (us *unitutilsuite) testunitgetmapkeys() {
    for i := range testunitgetmapkeys {
        us.t().run(testunitgetmapkeys[i].name, func(t *testing.t) {
            gotkeys := getmapkeys(testunitgetmapkeys[i].inputmap)
        })
    }
}
Copy after login

and

type interface{} of testunitgetmapkeys[i].inputmap does not match map[t]u (cannot infer t and u)
Copy after login

This has been fixed with explicit conversion

gotKeys := getMapKeys(testUnitGetMapKeys[i].inputMap.(map[string]string))
Copy after login

Is there a way to automate these tests without having to perform explicit conversions for each input test variable?

Workaround

Note that unless your generic function performs some type-specific logic in addition to the generic logic, you will learn nothing by testing the function against different types. The function's general logic is the same for all types in the type parameter's type set, so it can be fully performed using a single type.

But if you want to run tests against different types, you can simply do the following:

var testUnitGetMapKeys = []struct {
    name string
    got  any
    want any
}{
    {
        name: "string keys",
        got:  getMapKeys(map[string]int{"foo": 1, "bar": 2, "baz": 3}),
        want: []string{"foo", "bar", "baz"},
    },
    {
        name: "int keys",
        got:  getMapKeys(map[int]string{1: "foo", 2: "bar", 3: "baz"}),
        want: []int{1, 2, 3},
    },
    {
        name: "float64 keys",
        got:  getMapKeys(map[float64]bool{1.0: true, 2.5: false, 3.1415: true}),
        want: []float64{1.0, 2.5, 3.1415},
    },
}

// ...

func (us *UnitUtilSuite) TestUnitGetMapKeys() {
    for _, tt := range testUnitGetMapKeys {
        us.T().Run(tt.name, func(t *testing.T) {
            if !reflect.DeepEqual(tt.got, tt.want) {
                t.Errorf("got=%v; want=%v", tt.got, tt.want)
            }
        })
    }
}
Copy after login

The above is the detailed content of Writing unit tests for generic functions in golang. For more information, please follow other related articles on the PHP Chinese website!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template