Reputation: 6953
I'm trying to do a test:
slice
of struct
s with input
and expect
.int
or Error
.The goal is to expect an Error if the input will cause an invalid result. I've learnt that it's not recommended to return an error string in Go. How can I expect an error whilst doing unit testing in Go?
Here's the code:
func arrIdx(arr []int, idx int) (int, error) {
if idx >= 0 && idx < len(arr) {
return arr[idx], nil
}
return 0, fmt.Errorf("This is an error")
}
func TestArrIdx(t *testing.T) {
arr := []int{1, 2, 3, 4, 5}
tests := []struct {
arr []int
idx int
expect int // or an error
}{
{arr, len(arr) - 1, 5, nil},
{arr, 1, 2, nil},
// {arr, -1, 0, t.Error},
}
for _, test := range tests {
testName := fmt.Sprintf("%d", test.input)
t.Run(testName, func(t *testing.T) {
got := arr[test.input]
if got != test.expect {
t.Errorf("got %v, want %v", got, test.expect)
} else {
fmt.Printf("got %v expect %v\n", got, test.expect)
}
})
}
}
Upvotes: 0
Views: 1531
Reputation: 5060
I am not entirely sure what you are trying to do. Usually, you write methods that you want to test. Those methods have expected and unexpected results. You write unit tests to inject expected and unexpected input to generate those expected and unexpected results so your unit tests can make sure your methods are doing what they are built to do.
That being said, I could modify your block of code to handle errors, but I am not sure that is what you want:
package so_test
import (
"fmt"
"testing"
)
func TestArrIdx(t *testing.T) {
arr := [5]int{1, 2, 3, 4, 5}
tests := []struct {
input int
expect int
err error
}{
{len(arr) - 1, 5, nil},
{1, 2, nil},
{0, 0, fmt.Errorf("this is an error")},
}
for _, test := range tests {
testName := fmt.Sprintf("%d", test.input)
t.Run(testName, func(t *testing.T) {
if test.err != nil {
t.Errorf("received error '%v'", test.err)
} else {
got := arr[test.input]
if got != test.expect {
t.Errorf("got %v, want %v", got, test.expect)
} else {
fmt.Printf("got %v expect %v\n", got, test.expect)
}
}
})
}
}
Or, maybe this is closer to what you were hoping to do?
package so_test
import (
"fmt"
"testing"
)
// our unit test of the DoSomething() function
func TestDoSomething(t *testing.T) {
tests := []struct {
input int
expect int
err error
}{
{1, 2, nil},
{2, 2, fmt.Errorf("this is an error")},
{0, 0, fmt.Errorf("this is a DIFFERENT error")}, // will always fail
}
for _, test := range tests {
result, err := DoSomething(test.input)
if test.err != nil {
if err == nil {
t.Errorf("expected error '%v', received none\n", test.err)
} else if err.Error() != test.err.Error() {
t.Errorf("expected error: '%v', received '%v'\n", test.err, err)
} else {
fmt.Printf("expected error '%v', received error: '%v'\n", test.err, err)
}
} else {
if result != test.expect {
t.Errorf("got %v, want %v", result, test.expect)
} else {
fmt.Printf("got %v expect %v\n", result, test.expect)
}
}
}
}
// our function to test
func DoSomething(something int) (int, error) {
if something == 1 {
return 2, nil;
}
return 0, fmt.Errorf("this is an error")
}
Upvotes: 1