Home > front end >  Need to unittest golang error fs.PathError
Need to unittest golang error fs.PathError

Time:09-17

Im trying to catch an error and do a unittest check for the specific error object here is the prod function Im testing:

const command = "/tmp/cmd"

type RedisAdapter struct {
    modeStatus bool
}

func (r RedisAdapter) Enable(client domain.client) error {
    cmdArgs := []string{
        "redis-job-shard-pause",
        strconv.Itoa(client.Shard()),
        strconv.Itoa(client.Duration()),
    }
    cmd := fmt.Sprintf("%v", command)
    out, err := exec.Command(cmd, cmdArgs...).Output()
    fmt.Printf("%v", string(out))
    return err
}

Unittest code that run a test when error=nil and when error=fs.PathError:

func TestEnableService_SetEnable(t *testing.T) {
    type fields struct {
        LoadEnablePort out.EnablePort
    }
    type args struct {
        client domain.Client
    }
    fileNotFound := fs.PathError{
        Op:   "fork/exec",
        Path: "/tmp/cmd",
        Err:  syscall.ENOENT,
    }
    tests := []struct {
        name   string
        fields fields
        args   args
        want   error
    }{
        {
            "Enable Redis",
            fields{
                LoadEnablePort: redis.RedisAdapter{},
            },
            args{
                client: domain.Client{},
            },
            nil,
        },
        {
            "enable_redis_cmd_not_found",
            fields{
                LoadEnablePort: redis.RedisAdapter{},
            },
            args{
                client: domain.Client{},
            },
            &fileNotFound,
        },
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            s := EnableService{
                LoadEnablePort: tt.fields.LoadEnablePort,
            }
            if got := s.LoadEnablePort.Enable(tt.args.client); got != tt.want {
                t.Errorf("LoadEnablePort.RedisAdapter.Enable = %v, want %v", got, tt.want)
            }
        })
    }
}

The nil test works fine but when I catch the second test even if the object shows exactly the same in the debugger cannot tell why the test fails:

https://i.stack.imgur.com/CTtfk.png

Notice how the "got" variable is exactly the same as the "tt.want" variable objects and in the end I have the following failed test:

=== RUN   TestEnableService_SetEnable/enable_redis_cmd_not_found
    setModeService_test.go:116: LoadEnablePort.RedisAdapter.Enable = fork/exec /tmp/cmd: no such file or directory, want fork/exec /tmp/cmd: no such file or directory
    --- FAIL: TestEnableService_SetEnable/enable_redis_cmd_not_found (549.32s)

Thanks a lot for your help.

CodePudding user response:

both error values are comparable, they hold pointers to fs.PathError structs.

Their addresses differs, thus, they are not the same.

If you were dereferencing them, they equal.

https://play.golang.org/p/ZMoEahbyIX_E

You should use errors.Is or errors.As.

Equality operator is specified here https://golang.org/ref/spec#Comparison_operators

It says

...
Interface values are comparable. 
Two interface values are equal if they have 
identical dynamic types and equal dynamic values 
or if both have value nil.
...
  • Related