【发布时间】:2015-04-09 16:53:21
【问题描述】:
我正在尝试创建一个简单的模拟,用于使用 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 背景,我通常会在 LicenseManger 上修改 ListLicenses() 方法以进行模拟,但我似乎无法在 Go 中提出类似的模式或方法。
到目前为止,我已经尝试使用 govmomi Client 结构作为匿名成员和“构造函数”NewVCenter() 创建包装器结构 VCenterClient,以使用模拟逻辑创建包装器结构的新实例:
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 类型的接口。但是,我正在努力寻找替代方案。
任何关于更好的设计模式或在这种情况下正确使用接口的帮助将不胜感激。
【问题讨论】:
-
可能值得注意的是,采用单一方法
interface的 API 可以重写为采用函数类型。见stackoverflow.com/a/63557675/12817546。
标签: unit-testing interface go mocking vsphere