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

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

理解 Go 中的接口和模擬

理解 Go 中的接口和模擬

Go
慕萊塢森 2022-06-27 09:37:04
2·1我正在嘗試為 AWS 服務 ( ECR ) 構建抽象。這是代碼:type ECR struct {    Client ecriface.ECRAPI    Ctx    context.Context}// ECRCreate establishes aws session and creates a repo with provided inputfunc (e *ECR) ECRCreate(ecrInput *ecr.CreateRepositoryInput) {    result, err := e.Client.CreateRepositoryWithContext(e.Ctx, ecrInput)    if err != nil {        if aerr, ok := err.(awserr.Error); ok {            switch aerr.Code() {            case ecr.ErrCodeServerException:                log.Errorln(ecr.ErrCodeServerException, aerr.Error())            case ecr.ErrCodeInvalidParameterException:                log.Errorln(ecr.ErrCodeInvalidParameterException, aerr.Error())            case ecr.ErrCodeInvalidTagParameterException:                log.Errorln(ecr.ErrCodeInvalidTagParameterException, aerr.Error())            case ecr.ErrCodeTooManyTagsException:                log.Errorln(ecr.ErrCodeTooManyTagsException, aerr.Error())            case ecr.ErrCodeRepositoryAlreadyExistsException:                log.Errorln(ecr.ErrCodeRepositoryAlreadyExistsException, aerr.Error())            case ecr.ErrCodeLimitExceededException:                log.Errorln(ecr.ErrCodeLimitExceededException, aerr.Error())            case ecr.ErrCodeKmsException:                log.Errorln(ecr.ErrCodeKmsException, aerr.Error())            default:                log.Errorln(aerr.Error())            }        } else {            // Print the error, cast err to awserr.Error to get the Code and            // Message from an error.            log.Errorln(err.Error())        }        return    }    log.Infof("Result: %v", result)}要模擬 aws sdk 創建存儲庫調用: type mockECRClient struct {    ecriface.ECRAPI}這有效。但是,我對這里的界面和組合的使用有點困惑。ECRAPI 由 ecriface 包定義,我實現了接口的簽名之一,并且仍然能夠使用模擬客戶端mockSvc。問題:這是如何運作的?這是模擬接口的慣用方式嗎?ECRAPI接口的其他方法呢?那些是如何照顧的?那么我的理解是否正確,我們可以定義具有任意數量的方法簽名的接口,將該接口嵌入到結構中,然后將結構傳遞到預期接口的任何位置。但這意味著,我跳過實現我的接口的其他簽名?我想我在這里遺漏了一些重要的概念,請指教!
查看完整描述

1 回答

?
aluckdog

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

簡短的回答是:這是有效的,因為測試的函數只調用您明確定義的方法。如果它調用其他任何東西,它將失敗。


這是如何發生的:


該mockECRClient結構嵌入了接口,因此它具有該接口的所有方法。但是,要調用任何這些方法,您必須將該接口設置為實現:


x:=mockECRClient{}

x.ECRAPI=<real implementation of ECRAPI>

Func對定義為 for的 x.Func() 的ECRAPI調用實際上會調用x.ECRAPI.Func(). 由于您沒有設置 ECRAPI,因此x.ECRAPI上面是 nil,并且您調用的任何使用接收器的方法都會恐慌。


mockECRClient但是,您為:定義了一個方法CreateRepositoryWithContext。當你調用x.CreateRepositoryWithContext時,方法屬于x和不屬于x.ECRAPI,接收者將是x,所以它工作。


查看完整回答
反對 回復 2022-06-27
  • 1 回答
  • 0 關注
  • 132 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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