草庐IT

unit-testing - golang 中用于模拟第三方库的接口(interface)

coder 2023-06-26 原文

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

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

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

NewClient() 返回一个指向 Client 结构的指针,Client.LicenseManager() 返回一个 LicenseManager 结构的实例,而 LicenseManager.ListLicenses() 返回包含许可信息的结构片段。来自 Python 背景,我通常会猴子修补 LicenseManger 上的 ListLicenses() 方法进行模拟,但我似乎无法想出一个可比较的模式或 Go 中的方法论。

至此,我已经尝试创建一个包装器结构 VCenterClient,将 govmomi Client 结构作为匿名成员,并使用“构造函数”函数 NewVCenter( ) 使用模拟逻辑创建包装器结构的新实例:

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}
}

...但是我在使用接口(interface)正确抽象 govmomi 库中的嵌套结构时遇到了问题。我知道上面的方法不会起作用,因为 govmomi.LicenseManager() 返回类型为 govmomi.LicenseManager 的结构和我的 VCenterClientInterface.LicenseManager() 方法返回类型为 LicenseManager 的接口(interface)。但是,我正在努力寻找替代方案。

在这种情况下,任何有关更好的设计模式或正确使用接口(interface)的帮助都将不胜感激。

最佳答案

这个库是一个 SOAP 客户端(http://godoc.org/github.com/vmware/govmomi/vim25/soap#Client)。使用 net/http/httptest ( http://golang.org/pkg/net/http/httptest/ ) 在 HTTP 层进行抽象,或者使用您自己的 HTTPRoundtripper 来模拟响应。

关于unit-testing - golang 中用于模拟第三方库的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28418430/

有关unit-testing - golang 中用于模拟第三方库的接口(interface)的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  3. ruby - 在 Ruby 中用键盘诅咒数组浏览 - 2

    我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作

  4. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  5. ruby-on-rails - 在这种情况下我如何模拟一个对象?没有明显的方法可以用模拟替换对象 - 2

    假设我在Store的模型中有这个非常简单的方法:defgeocode_addressloc=Store.geocode(address)self.lat=loc.latself.lng=loc.lngend如果我想编写一些不受地理编码服务影响的测试脚本,这些脚本可能已关闭、有限制或取决于我的互联网连接,我该如何模拟地理编码服务?如果我可以将地理编码对象传递到该方法中,那将很容易,但我不知道在这种情况下该怎么做。谢谢!特里斯坦 最佳答案 使用内置模拟和stub的rspecs,你可以做这样的事情:setupdo@subject=MyCl

  6. ruby - "public/protected/private"方法是如何实现的,我该如何模拟它? - 2

    在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定

  7. ruby - 在 RSpec 中 stub /模拟全局常量 - 2

    我有一个gem,它有一个根据Rails.env的不同行为的方法:defself.envifdefined?(Rails)Rails.envelsif...现在我想编写一个规范来测试这个代码路径。目前我是这样做的:Kernel.const_set(:Rails,nil)Rails.should_receive(:env).and_return('production')...没关系,只是感觉很丑。另一种方法是在spec_helper中声明:moduleRails;end而且效果也很好。但也许有更好的方法?理想情况下,这应该有效:rails=double('Rails')rails.sho

  8. ruby 单元测试 : run some code after each failed test - 2

    在Test::Unit中的ruby​​单元测试断言失败后,在执行teardown之前,是否有一些简洁优雅的方法来立即执行我的代码?我正在做一些自动化的GUI测试,并希望在出现问题后立即截图。 最佳答案 如果您使用的是1.9,请不要使用Test::Unit::TestCase作为您的基类。对其进行子类化并覆盖#run_test以进行救援,截取屏幕截图并重新提出:classMyAbstractTestCase或者,我认为这实际上是最简洁的方法,您可以使用before_teardownHook:classMyTestCase这不适用于1.

  9. ruby-on-rails - rspec 模拟对象属性赋值 - 2

    我有一个rspec模拟对象,一个值赋给了属性。我正在努力在我的rspec测试中满足这种期望。只是想知道语法是什么?代码:defcreate@new_campaign=AdCampaign.new(params[:new_campaign])@new_campaign.creationDate="#{Time.now.year}/#{Time.now.mon}/#{Time.now.day}"if@new_campaign.saveflash[:status]="Success"elseflash[:status]="Failed"endend测试it"shouldabletocreat

  10. ruby - 如何使用 rspec stub /模拟对命令行的调用? - 2

    我正在尝试测试命令行工具的输出。如何使用rspec来“伪造”命令行调用?执行以下操作不起作用:it"shouldcallthecommandlineandreturn'text'"do@p=Pig.new@p.should_receive(:run).with('my_command_line_tool_call').and_return('resulttext')end如何创建stub? 最佳答案 使用newmessageexpectationsyntax:规范/虚拟规范.rbrequire"dummy"describeDummy

随机推荐