doushi1912 2015-02-09 20:11
浏览 189

golang中用于模拟第三方库的接口使用

I'm trying to create a simple mock for unit testing some code using the VMware vSphere API client - govmomi - but I'm having trouble finding a usable pattern.

A simple use case for the client library would be to retrieve the installed licenses for a vSphere cluster:

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

NewClient() returns a pointer to a Client structure, Client.LicenseManager() returns an instance of a LicenseManager structure, and LicenseManager.ListLicenses() returns a slice of structures containing the license info. Coming from a Python background, I'd usually monkey patch the ListLicenses() method on LicenseManger for a mock, but I can't seem to come up with a comparable pattern or methodology in Go.

To this point, I've tried creating a wrapper structure VCenterClient with the govmomi Client structure as an anonymous member and a "constructor" function NewVCenter() to create new instances of the wrapper structure with logic for 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}
}

...but I having trouble using interfaces to properly abstract the nested structures in the govmomi library. I know the above will not work as govmomi.LicenseManager() returns a structure of type govmomi.LicenseManager and my VCenterClientInterface.LicenseManager() method returns an interface of type LicenseManager. However, I'm struggling to find an alternative.

Any help on a better design pattern or proper use of interfaces in this case would be much appreciated.

  • 写回答

1条回答 默认 最新

  • douxue4242 2015-02-09 20:34
    关注

    This library is a SOAP client (http://godoc.org/github.com/vmware/govmomi/vim25/soap#Client). Abstract at the HTTP layer with net/http/httptest (http://golang.org/pkg/net/http/httptest/) or by using your own HTTPRoundtripper to mock the response.

    评论

报告相同问题?

悬赏问题

  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)