Home >Backend Development >Golang >How to compare Go slices and NaN elements in unit tests?

How to compare Go slices and NaN elements in unit tests?

WBOY
WBOYforward
2024-02-12 13:00:091039browse

如何在单元测试中比较 Go 切片和 NaN 元素?

#php Editor Baicao Comparing Go slices and NaN elements is a common problem in unit tests. When dealing with slices, we often need to compare two slices for equality, but the comparison becomes complicated when the slice contains NaN elements. NaN is a special floating point number, which means it is not a numeric value. In Go, use the IsNaN function in the math package to determine whether a floating point number is NaN. We can implement slice comparison operations by iterating through each element in the slice and using the IsNaN function to determine whether it is NaN.

Question content

I need to compare 2 slices in a unit test, I think the assert package should solve this problem, but it doesn't work with nan:

import (
    "github.com/stretchr/testify/assert"
)

func callme() []float64 {
    return []float64{math.nan()}
}

func testcallme(t *testing.t) {
    assert.equal(t, []float64{math.nan()}, callme())
}

The output is:

Error:          Not equal: 
                            expected: []float64{NaN}
                            actual  : []float64{NaN}
                            
                            Diff:
            Test:           TestCallMe

I know that one of the properties of nan is not equal to itself, but on the other hand I receive the expected result from the function.

I want to know how to solve this problem - get concise unit test assertions and clear output?

As an alternative, I could avoid using assert and call math.isnan on each element of both slices, but this would look extremely verbose in a unit test .

Solution

github.com/google/go-cmp/cmp package for more complex comparisons. cmpopts.equatenans can be used to easily compare data structures that may contain nan.

package calc_test

import (
    "math"
    "testing"

    "github.com/google/go-cmp/cmp"
    "github.com/google/go-cmp/cmp/cmpopts"
)

func calc(n float64) []float64 {
    return []float64{n, math.NaN()}
}

func TestCalc(t *testing.T) {
    want := []float64{1, math.NaN()}

    got := calc(1)  // PASS.
    if !cmp.Equal(got, want, cmpopts.EquateNaNs()) {
        t.Errorf("calc: got = %v; want = %v", got, want)
    }

    got = calc(2)   // FAIL with differences.
    if diff := cmp.Diff(want, got, cmpopts.EquateNaNs()); diff != "" {
        t.Errorf("calc: diff (-want +got) = \n%s", diff)
    }
}

The above is the detailed content of How to compare Go slices and NaN elements in unit tests?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete
Previous article:CORS grpc gateway GoLangNext article:CORS grpc gateway GoLang