2 回答
TA贡献1111条经验 获得超0个赞
首先,对于大多数用途,使用ptest
包可能是测试 pubsub 的更简单的方法。但是当然,您的具体问题可以适用于任何库,并且下面的方法对很多事情都有用,而不仅仅是模拟pubsub
。
使用接口来模拟这样的库的更广泛目标是可行的。但是,当您希望模拟的库返回您无法模拟的具体类型(可能是由于未报告的字段)时,情况会很复杂。所采取的方法比通常值得的要复杂得多,因为可能有更简单的方法来测试代码。
但是,如果您打算这样做,则必须采取的方法是不要将整个包包装在接口中,而不仅仅是您希望模拟的特定方法。
您还需要包装您希望模拟的任何类型,这些类型也由您的接口返回或接受。这通常意味着您还需要修改生产代码(而不仅仅是测试代码),因此这有时可能会破坏现有代码库的交易。
我以前通常这样做的地方是在模拟标准库的 sql 驱动程序之类的东西时,但这里可以应用相同的方法。本质上,您需要为您的pubsub
库创建一个包装器包,甚至可以在生产代码中使用它。同样,这可能会对现有代码库造成很大的干扰,但只是为了说明目的。使用您定义的接口:
package mypubsub
import "cloud.google.com/go/pubsub"
type Receiver interface {
Recieve(context.Context, func(context.Context, *pubsub.Message) error)
}
type SubscriptionMaker interface {
Subscription(string) Receiver
}
然后,您可以包装默认实现,以便在生产代码中使用:
// defaultClient wraps the default pubsub Client functionality.
type defaultClient struct {
*pubsub.Client
}
func (d defaultImplementation) Subscription(name string) Receiver {
return d.Client.Subscription()
}
当然,您需要扩展此包以包装pubsub您正在使用的大部分或全部包。这可能有点令人畏惧。
但是一旦完成此操作,就可以mypubsub在代码中的任何地方使用您的包,而不是直接依赖于该pubsub包。现在,您可以在需要测试的任何地方轻松更换模拟实现。
TA贡献1817条经验 获得超14个赞
这是不可能的。
在接口上定义方法的类型签名时,它必须完全匹配。func (c *Client) Subscription(id string) *Subscription
返回 a *Subscription
,并且 a*Subscription
是有效的Receiver
,但它不算符合接口方法Subscription(string) Receiver
。Go 需要函数签名的精确匹配,而不是通常用于接口的鸭子类型风格。
- 2 回答
- 0 关注
- 134 浏览
添加回答
举报