【问题标题】:Need to unittest golang error fs.PathError需要对 golang 错误 fs.PathError 进行单元测试
【发布时间】:2021-11-06 12:43:42
【问题描述】:

我试图捕捉一个错误并对特定的错误对象进行单元测试检查,这里是 prod 函数我正在测试:

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
}

在 error=nil 和 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)
            }
        })
    }
}

nil 测试工作正常,但是当我捕获第二个测试时,即使对象在调试器中显示完全相同,也无法说明测试失败的原因:

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

注意“got”变量与“tt.want”变量对象完全相同,最后我有以下失败的测试:

=== 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)

非常感谢您的帮助。

【问题讨论】:

    标签: unit-testing go error-handling


    【解决方案1】:

    两个错误值是可比较的,它们持有指向 fs.PathError 结构的指针。

    它们的地址不同,因此它们不一样。

    如果你取消引用它们,它们是相等的。

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

    您应该使用errors.Iserrors.As

    这里指定了等式运算符https://golang.org/ref/spec#Comparison_operators

    它说

    ...
    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.
    ...
    

    【讨论】:

    • 太棒了,完成了这项工作,非常感谢@mh-cbon
    猜你喜欢
    • 2016-12-14
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多