Better approach for error/non-error in table tests
I notice I keep running into this, so let me open an issue;
When writing table-tests, I usually combine "happy" and "unhappy" tests, which means that for some tests, I'd be checking for an error, and for the happy tests, check that no error occurs.
For example;
func TestErrorOrNot(t *testing.T) {
doSomething := func(withError bool) error {
if withError {
return errors.New("something went wrong")
}
return nil
}
for _, test := range []struct {
withErr bool
errString string
}{{withErr: true, errString: "something went wrong"}, {}} {
err := doSomething(test.withErr)
if test.errString != "" {
assert.Error(t, err, test.errString)
}
assert.NilError(t, err)
}
}
I'd like to get rid of the if test.errString != "" { in these tests;
Initially thought; let's use assert.Error(t, err, test.errString), which fails, because a nil error is not the same as an empty error-string. Using assert.ErrorContains(t, err, test.errString) has the same issue, because "" must be included in the error (which isn't the case if there's no error at all)
Wondering if there's a better approach, or if a new utility should be added that accepts "empty error string" as "no error is produced".
@vdemeester @dnephin
I will generally do one of the following:
- write success cases in a separate table from error cases; or
- use an
ifin the test body, similar to what you have illustrated above, except I will generallyreturnafterassertbecause the test is in at.Run(); or - instead of
expectedErr stringin the testcase struct I will use a function that can be passed to https://godoc.org/gotest.tools/assert#ErrorType:
func noError(err error) bool {
return err == nil
}
Maybe the last option fits your case?
I think a function that treats "" as "no error" is not very intuitive.