I need to compare 2 slices in unit tests and I thought assert
package should solve this but it doesn't work with NaNs:
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 understand that it's a property of NaN to be not equal to itself but on the other hand I receive the expected result from the function.
I wonder how to solve that - to have a concise unit test assertion and a clear output?
As an alternative I can avoid using assert
and call math.IsNaN
on every element of both slices but that will look extra verbose in unit tests.
CodePudding user response:
The github.com/google/go-cmp/cmp package is typically recommended for more complex comparisons. cmpopts.EquateNaNs can be used to easily compare data structures which may contain NaNs.
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)
}
}