英文:
Need to unittest golang error fs.PathError
问题
我正在尝试捕获错误并对特定错误对象进行单元测试检查,这是我正在测试的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)
非常感谢您的帮助。
英文:
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.
答案1
得分: 2
两个错误值是可比较的,它们持有对fs.PathError
结构体的指针。
它们的地址不同,因此它们不相同。
如果你对它们进行解引用,它们是相等的。
https://play.golang.org/p/ZMoEahbyIX_E
你应该使用errors.Is
或errors.As
。
相等运算符在这里有说明https://golang.org/ref/spec#Comparison_operators
它说
...
接口值是可比较的。
如果两个接口值具有相同的动态类型和相等的动态值,或者两者都具有值nil,则它们是相等的。
...
英文:
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.
...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论