在golang中使用接口来模拟第三方库

时间:2015-02-09 20:11:59

标签: unit-testing interface go mocking vsphere

我正在尝试使用VMware vSphere API客户端govmomi创建一个单独测试某些代码的简单模拟器 - 但我找不到可用的模式。

客户端库的一个简单用例是检索vSphere群集的已安装许可证:

vclient, err := govmomi.NewClient(*vcurl, true)
if err != nil {
 return err
}
lic, err := vclient.LicenseManager().ListLicenses()

NewClient()返回指向客户端结构的指针,Client.LicenseManager()返回LicenseManager结构的实例,LicenseManager.ListLicenses()返回包含许可证信息的结构片段。来自Python背景,我通常会在ListLicenses()上使用LicenseManger方法修补模拟,但我似乎无法在Go中提出类似的模式或方法。

到目前为止,我尝试使用govmomi VCenterClient结构创建一个包装结构Client作为匿名成员和一个"构造函数"函数NewVCenter()用于创建包含mocks逻辑的包装器结构的新实例:

import (
 "net/url"


 "github.com/vmware/govmomi"
 "github.com/vmware/govmomi/vim25/types"
)


type VCenterClient struct {
 VCenterClientInterface
}


type VCenterClientInterface interface {
 LicenseManager() LicenseManager
}


type LicenseManager interface {
 ListLicenses() ([]types.LicenseManagerLicenseInfo, error)
}


type VCenterClientMock struct{}
type LicenseManagerMock struct{}


func (v *VCenterClientMock) LicenseManager() LicenseManager {
 return LicenseManagerMock{}
}


func (l LicenseManagerMock) ListLicenses() ([]types.LicenseManagerLicenseInfo, error) {
 return make([]types.LicenseManagerLicenseInfo, 0), nil
}


func NewVCenterClient(uri string, mock bool) *VCenterClient {
 if mock {
 return &VCenterClient{&VCenterClientMock{}}
 }


 vcurl, _ := url.Parse(uri)
 vclient, _ := govmomi.NewClient(*vcurl, true)
 return &VCenterClient{vclient}
}

...但我无法使用接口来正确抽象govmomi库中的嵌套结构。我知道上面的内容不起作用,因为govmomi.LicenseManager()返回类型为govmomi.LicenseManager的结构,而我的VCenterClientInterface.LicenseManager()方法返回类型为LicenseManager的接口。但是,我正在努力寻找替代方案。

对于更好的设计模式或在这种情况下正确使用接口的任何帮助都将非常感激。

1 个答案:

答案 0 :(得分:2)

此库是SOAP客户端(http://godoc.org/github.com/vmware/govmomi/vim25/soap#Client)。摘要在HTTP层使用net / http / httptest(http://golang.org/pkg/net/http/httptest/)或使用您自己的HTTPRoundtripper来模拟响应。