亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 golang 單元測試中模擬特定的錯誤類型

在 golang 單元測試中模擬特定的錯誤類型

Go
慕田峪4524236 2022-07-18 15:53:07
我一直致力于處理一些 golang 函數中的軟故障,并希望為各種故障場景創建一些單元測試。例如,一些檢查包括:        switch err := err.(type) {        case net.Error:                if err.(net.Error).Temporary() || err.(net.Error).Timeout() {                        ...                }        case *url.Error:                if err, ok := err.Err.(net.Error); ok && err.Timeout() {                        ...                }        case *net.OpError:                if syscallErr, ok := err.Err.(*os.SyscallError); ok {                        if syscallErr.Err == syscall.ECONNRESET {                                ...                        }                }        ...我相信我只需要我的模擬函數來返回與這些條件兼容的錯誤。我看到 net.Error、net.OpError、url.Error 和 os.SyscallError 類型已導出。但是,我找不到任何人構造 net.Error 值并返回它的示例——人們投入了大量工作來創建一個以各種方式失敗的外部進程,但沒有返回帶有 Timeout 函數的 net.Error 的示例返回真。同樣,我找不到任何包裝不是由 fmt.Errorf 產生的錯誤的示例,因此我不確定在不使用基本內置錯誤類型時是否涉及更多的錯誤。Wrap()。
查看完整描述

2 回答

?
郎朗坤

TA貢獻1921條經驗 獲得超9個贊

https://golang.org/pkg/net/#Error是一個接口,并且定義Timeout并且Temporary將是微不足道的,因為它們只是返回bool。


package main


import(

        "fmt"

        "net"

)


type mockNetError struct {

        temporary bool

        timeout bool

}


func (e *mockNetError)Error() string {

        return fmt.Sprintf("mockNetworkError: timeout %b, temporary %b", e.timeout, e.temporary)

}


func (e *mockNetError)Temporary() bool{

        return e.temporary

}


func (e *mockNetError)Timeout() bool{

        return e.timeout

}

func main() {

        var err error = new(mockNetError)

        if nerr, ok := err.(net.Error); ok {

                fmt.Println("It was a network error! %s", nerr.Error())

        }

}

但是,因為net.Error是接口類型,err.(type)所以永遠不會返回它。在我的代碼中,我斷言它可能滿足該接口,這與詢問它是否是err接口中值的類型不同。


您提到的其他錯誤net不是接口(盡管它們確實滿足net.Error)。


https://blog.golang.org/go1.13-errors討論了錯誤包裝在 go 中的工作原理。


約定而不是更改:包含另一個錯誤的錯誤可能會實現返回底層錯誤的 Unwrap 方法。


原因%w幾乎總是這樣做的,因為人們幾乎總是在錯誤中添加額外的文本。


實際上,是一個可以通過提供方法net.OsError包裝另一個錯誤的示例。Unwrap()


如果您想創建這樣的錯誤,只需:


fmt.Println(net.OpError{

   Op: "mock", 

   Net: "mock",

   Source: &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 1234 },                

   Addr: &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 12340 },

   Err: fmt.Errorf("Mock net.OpError"),

})


查看完整回答
反對 回復 2022-07-18
?
三國紛爭

TA貢獻1804條經驗 獲得超7個贊

基于 Daniel Farrell 的回答,我發現了一個模擬 os.SyscallError 的示例,該示例深埋在適用于 Golang 的 AWS 開發工具包中。把它們放在一起,我們得到這個:

return nil, &net.OpError{
                Op:     "mock",
                Net:    "mock",
                Source: &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 1234},
                Addr:   &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 12340},
                Err:    &os.SyscallError{Syscall: "read", Err: syscall.ECONNRESET},
               }


查看完整回答
反對 回復 2022-07-18
  • 2 回答
  • 0 關注
  • 121 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號