unit-testing - 如何优雅地测试 Go 中包含多个客户端的方法?
问题描述
我有一个Client
包含多个客户端(etcd 和 libvirt)的结构。就像是:
type Client struct {
etcd *clientv3
libvirt *libvirt.Connect
}
一旦我的图书馆的客户想要关闭它的句柄,我想关闭这两个。所以我有:
func (c *Client) Close() error {
c.etcd.Close()
c.libvirt.Close()
// Error handling excluded for brevity
}
什么是测试这个的优雅方法?我目前最好的选择是创建两个接口,一个用于两个包装客户端中的每一个。这些接口将包括我的库使用的两个客户端的每一个方法。这应该使得传递某种模拟而不是真正的客户变得相对容易。这可能是前进的方向,但感觉很尴尬。
我还有哪些其他选择?
解决方案
正如我在评论中提到的,您可以创建一个ClosableClient
如下所示的。由于您的每个客户都有Close
方法,因此您可以这样做。在您的测试文件中,您可以创建只需要实现Close
方法的模拟客户端。您不需要使接口实现所有方法。在您的代码中,您可以使用类型断言将其转换ClosableClient
为特定的客户端以访问其功能。这是类型断言的一个很好的例子。
我添加了代码片段来展示如何使用类型断言来获取底层结构。测试文件中的模拟客户端不需要实现 Foo 和 Bar 方法,因为接口ClosableClient
只需要Close
方法。
type ClosableClient interface {
Close()
}
type Etcd struct{}
func (e *Etcd) Close() {
fmt.Println("etcd closing")
}
func (e *Etcd) Foo() {
fmt.Println("etcd foo")
}
type Libvirt struct{}
func (l *Libvirt) Close() {
fmt.Println("libvirt closing")
}
func (l *Libvirt) Bar() {
fmt.Println("libvirt bar")
}
type Client struct {
etcd ClosableClient
libvirt ClosableClient
}
func (c *Client) Close() {
c.etcd.Close()
c.libvirt.Close()
}
func (c *Client) FooBar() {
etcd, ok := c.etcd.(*Etcd)
if !ok {
panic("etcd is of incorrect type")
}
etcd.Foo()
libvirt, ok := c.etcd.(*Libvirt)
if !ok {
panic("libvirt is of incorrect type")
}
libvirt.Bar()
}
推荐阅读
- html - 角度自定义标签不呈现和执行功能
- python - 需要找到一组字符的所有可能组合
- javascript - Robin Herbots jquery.inputmask 允许许多值以逗号分隔
- node.js - 节点 js 中的 Sage pay 集成
- python - 补丁颜色全部在补丁集合中重置
- reactjs - 如何使用 ReactJS 创建可重用的插件
- php - 致命错误:require_once():在 C:\Users\zu 中打开所需的 'C:\core/vendor/autoload.php' (include_path='C:\xampp\php\PEAR') 失败
- javascript - 使用订单项属性自定义订单确认电子邮件
- python - fileinput.input() 如何工作?
- c# - Json.NET 不会使用自定义 getter 和不可变类型反序列化属性