如何解决将“字段”添加到 Golang 中的接口
我有一个“类”CustomClient,它执行一些 HTTP 操作并将一些数据保存在自定义结构中。 CustomClient 的成员之一是 Golang http.Client
type CustomClient struct {
commData CustomDataStruct
httpClient *http.Client
}
我正在尝试为 CustomClient 添加一些额外的“可测试性”。目前,我无法控制 httpClient 响应的 HTTP 响应类型。 CustomClient 只使用 httpClient 来运行 httpClient.Do(),所以我有一个想法来创建一个“接口”来实现这个方法,所以我想让它像:
type Client interface {
Do(req *http.Request) (*http.Response,error)
}
type CustomClient struct {
commData CustomDataStruct
httpClient Client
}
然后我使用 Do() 方法创建了自己的类 HttpClientMOCK,该方法将返回一些用于测试目的的自定义响应:
type HttpClientMOCK struct {
Transport *http.Transport
}
func NewHttpClientMOCK() *HttpClientMOCK {
c := &HttpClientMOCK{
Transport: &http.Transport{},}
return c
}
func (c *HttpClientMOCK) Do(req *http.Request) (*http.Response,error) {
// Do stuff
}
只有一个问题——CustomClient的其中一个“成员函数”手动分配了http.Client.Transport,原http.Client使用。该行如下所示:
func (cc *CustomClient) updateClient() {
transport := ... // Do some operations
cc.httpClient.Transport = transport
}
上一行给出了错误 - 未解析的引用'传输'
所以我猜 Golang 无法知道 http.Client 和 HttpClientMOCK 实际上都有这个成员 Transport 因为我的接口 Client 只指定了一种方法。
是否有解决此问题的方法? AFAIK 我的手被绑在这里,因为没有办法为接口定义“数据字段”。
解决方法
使用 Do
方法对 HTTP 客户端进行抽象非常好,但在代码后期,更改传输会破坏该抽象。这应该被审查,是否有任何限制理由这样做? (例如使用多个客户端证书来验证请求)
要使代码正常工作,始终可以强制转换为 *http.Client
:
func (cc *CustomClient) updateClient() {
if h,ok := cc.httpClient.(*http.Client); ok {
transport := ... // Do some operations
h.Transport = transport
}
}