Files
go-kata/04-errors-semantics/20-nil-interface-gotcha/myerror_test.go
T
2026-03-23 16:57:33 +02:00

128 lines
2.5 KiB
Go

package myerror
import (
"errors"
"fmt"
"testing"
)
func TestDoThingMatrix(t *testing.T) {
tests := []struct {
name string
fn func(bool) error
fail bool
wantNil bool
wantType string
}{
{
name: "BuggyDoThing returns typed nil (should NOT be nil)",
fn: BuggyDoThing,
fail: false,
wantNil: false,
wantType: "*myerror.MyError",
},
{
name: "BuggyDoThing returns error (fail=true)",
fn: BuggyDoThing,
fail: true,
wantNil: false,
wantType: "*myerror.MyError",
},
{
name: "FixedDoThing returns nil (should be nil)",
fn: FixedDoThing,
fail: false,
wantNil: true,
wantType: "<nil>",
},
{
name: "FixedDoThing returns error (fail=true)",
fn: FixedDoThing,
fail: true,
wantNil: false,
wantType: "*myerror.MyError",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.fn(tt.fail)
gotNil := err == nil
gotType := "<nil>"
if err != nil {
gotType = fmt.Sprintf("%T", err)
}
if gotNil != tt.wantNil {
t.Errorf("expected nil: %v, got: %v (type: %s, value: %#v)", tt.wantNil, gotNil, gotType, err)
}
if gotType != tt.wantType {
t.Errorf("expected type: %s, got: %s", tt.wantType, gotType)
}
})
}
}
func TestErrorsAsExtractionMatrix(t *testing.T) {
tests := []struct {
name string
wrap bool
expectOp string
}{
{
name: "Direct MyError",
wrap: false,
expectOp: "extract",
},
{
name: "Wrapped MyError",
wrap: true,
expectOp: "extract",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
orig := &MyError{Op: "extract"}
var err error = orig
if tt.wrap {
err = WrapError(err)
}
var me *MyError
if !errors.As(err, &me) {
t.Fatalf("errors.As failed to extract *MyError")
}
if me == nil || me.Op != tt.expectOp {
t.Fatalf("extracted wrong value: %#v", me)
}
})
}
}
func TestErrorMethodOutput(t *testing.T) {
tests := []struct {
name string
err *MyError
expectedMsg string
}{
{
name: "nil receiver",
err: nil,
expectedMsg: "<nil MyError>",
},
{
name: "normal error",
err: &MyError{Op: "test-operation"},
expectedMsg: "operation failed: test-operation",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
msg := tt.err.Error()
if msg != tt.expectedMsg {
t.Errorf("expected message: %q, got: %q", tt.expectedMsg, msg)
}
})
}
}