Reputation: 13
How would you write a test for a function that returns a value that could either be nil or a concrete value? I don't care about the actual value itself, I just care about whether the value has been returned or not.
type CustomType struct{}
func TestSomeFunc(t *testing.T) {
case := map[string]struct {
Input string
Expected *CustomType // expected result
Error error // expected error value
} {
"test case 1":
"input",
&CustomType{}, // could be nil or a concrete value
nil,
"test case 2":
"input",
nil, // could be nil or a concrete value
ErrSomeError,
}
actual, err := SomeFunc(case.Input)
if (actual != case.Expected) {
t.Fatalf(...)
}
}
and the function to be tested could look something like:
func SomeFunc(input string) (*CustomType, error) {
foo, err := doSomething()
if err != nil {
return nil, err
}
return foo, nil
}
I guess the logic I want is:
if ((case.Expected != nil && actual == nil) ||
(case.Expected == nil && actual != nil)) {
t.Fatalf(...)
}
Is there a better way of just asserting for existence rather than comparing concrete types?
Upvotes: 1
Views: 1498
Reputation: 30037
It's not much shorter than what you have, but I think what you want is for the test to pass only when (case.Expected == nil) == (actual == nil)
, comparing the (true
or false
) results of two comparisons against nil
. Here's a short program demonstrating:
package main
import (
"fmt"
)
func main() {
isNil, isNotNil, otherNotNil := []byte(nil), []byte{0}, []byte{1}
fmt.Println("two different non-nil values\t", (otherNotNil == nil) == (isNotNil == nil))
fmt.Println("a nil and a non-nil value\t", (isNil == nil) == (isNotNil == nil))
fmt.Println("two nil values\t\t\t", (isNil == nil) == (isNil == nil))
}
As user icza points out, you can change the outer ==
into a !=
(giving you something like (actual == nil) != (expected == nil)
) to get true
when there is a mismatch rather than when there is a match.
Upvotes: 3