英文:
How to handle json syntax error in a go test case?
问题
我正在测试一个场景,其中json.Unmarshal
失败并返回
&json.SyntaxError{msg:"unexpected end of JSON input", Offset:0}
代码如下:
err = json.Unmarshal(input, &data)
if err != nil {
return nil, err
}
测试用例期望这种类型的错误:
{
...
errorType: &json.SyntaxError{},
...
}
断言如下:
assert.Equal(t, tt.errorType, err)
但是失败了,因为错误消息不同:
expected: &json.SyntaxError{msg:"", Offset:0}
actual : &json.SyntaxError{msg:"unexpected end of JSON input", Offset:0}
我该如何处理?也许可以利用Error()
方法来处理?
英文:
I'm testing a scenario where json.Unmarshall
fails and returns
&json.SyntaxError{msg:"unexpected end of JSON input", Offset:0}
the code is like this:
err = json.Unmarshal(input, &data)
if err != nil {
return nil, err
}
test case is expecting this type of error:
{
...
errorType: &json.SyntaxError{},
...
}
the assertion is like this:
assert.Equal(t, tt.errorType, err)
which is failing because the error message is different:
expected: &json.SyntaxError{msg:"", Offset:0}
actual : &json.SyntaxError{msg:"unexpected end of JSON input", Offset:0}
How can I handle this? Perhaps making use of Error()
?
答案1
得分: 4
首先,直接创建这个 sentinel 错误是不可能的:
_ = &json.SyntaxError{msg: "unexpected end of JSON input", Offset: 0} // msg field is not exported
你能做的最接近的方法是检查错误的 类型。可以使用 errors.As
来实现:
var tt *json.SyntaxError
if errors.As(err, &tt) {
log.Printf("Syntax Error: %v", tt)
} else if err != nil {
log.Fatalf("Fatal: %#v", err)
}
你可以检查 Offset
字段,因为它是公开的。但是要比较非公开的 msg
字段,你需要使用 err.Error()
,但这可能不太稳定,因为随着时间的推移,文本可能会发生变化。
注意: 在这里无法使用 errors.Is
,因为它只测试错误的相等性:直接相等,或通过 error.Unwrap
进行嵌套。
由于这里的 json.SyntaxError
既不是被包装的,也不是 sentinel 错误,所以无法通过 errors.Is
进行匹配。
英文:
Firstly it's not possible to craft this sentinel error directly:
_ = &json.SyntaxError{msg: "unexpected end of JSON input", Offset: 0} // msg field is not exported
the closest you can come is to check for the error type. To do this use errors.As
var tt *json.SyntaxError
if errors.As(err, &tt) {
log.Printf("Syntax Error: %v", tt)
} else if err != nil {
log.Fatalf("Fatal: %#v", err)
}
https://go.dev/play/p/mlqGN2ypwBs
You can check the Offset
as that is public field. But to compare the non-public msg
field, you'd need to use err.Error()
- but this may be brittle as wording may change over time.
Note: errors.Is cannot be used here, as it only tests error equality: directly; or via error.Unwrap-ing.
Since the json.SyntaxError here is not wrapped - nor is it a sentinel error - it cannot be matched via errors.Is
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论