如何将不同的错误接口实现存储在一起,然后在 Go 中使用它们进行类型比较?
Posted
技术标签:
【中文标题】如何将不同的错误接口实现存储在一起,然后在 Go 中使用它们进行类型比较?【英文标题】:How can I store different error interface implementations together and then use them for type comparison in Go? 【发布时间】:2020-02-21 15:19:51 【问题描述】:我正在尝试在 go 中编写一个表测试,其中测试用例会导致不同的错误。然后我想检查错误的类型是否与测试用例中定义的错误类型匹配,使用errors.As()
。每个测试用例都由一个结构定义,因此结构中需要有一个类型可以容纳接口error
的任何实现,这也是为了验证测试中返回的类型是否正确。
我尝试过如下定义结构
type testCase struct
testInput string
expectedError error
我还有一些实现error
接口的自定义错误,比如说一个叫做myCustomError
然后我像这样声明该结构的变量:
mTest := testCase
testInput: "some failing string",
expectedError: myCustomError,
如果我再做这样的测试......
err := someFunc(mTest.testInput)
if errors.As(err, &mTest.expectedError)
// test have succeeded
... if 语句将始终返回 true
,无论返回哪种自定义错误类型。
我在 Go Playground 上做了一个最小的例子:https://play.golang.org/p/uMdbMvfcdQi
在操场示例中,我希望字符串“matching myError1”被打印两次,但是当值存储为普通的error
之前,它也匹配myError2
,然后用于检查类型变量错误。
甚至有可能做这样的事情吗?
【问题讨论】:
这里我想你想使用errors.Is
,而不是errors.As
@yazgazan 是正确的,Is
是您想要的。 (play.golang.org/p/5LdhUUaZxCd) "As
依次展开它的第一个参数,寻找可以分配给它的第二个参数的错误,它必须是一个指针。如果成功,它执行分配并返回 true。"
@yazgazan 如果返回的错误具有某种属性,这将不起作用,不幸的是它们在我的真实案例中具有(参见play.golang.org/p/JIsNFJ364te)它们也可能包含在其他一些错误中。我从问题中省略了这一点,以使其最小化。如果您对解决问题有一些想法,我很高兴听到它,否则将其发布为答案,我会将其标记为已解决,因为它回答了实际问题。
您可以实现Is(error) bool
方法,以便Is
适用于您的自定义类型:golang.org/pkg/errors/#Is。
如果您无法控制这些自定义错误类型,那么想到的唯一解决方案就是使用反射......
【参考方案1】:
在测试用例中存储一个指向目标值的指针。
type testCase struct
testInput string
expectedError interface
mTest := testCase
testInput: "some failing string",
expectedError: &myCustomError,
err := someFunc(mTest.testInput)
if errors.As(err, mTest.expectedError)
// test have succeeded
最小示例:https://play.golang.org/p/igJy9L_ui73
【讨论】:
以上是关于如何将不同的错误接口实现存储在一起,然后在 Go 中使用它们进行类型比较?的主要内容,如果未能解决你的问题,请参考以下文章