我有一个包含很多子方法的接口(interface)。
type InterfaceCheckout interface {
GetID() int
GetItems() []InterfaceCartItem
// ... then like 30more methods
}
我有一个只使用 GetItems 方法的方法。
func GetRates(checkoutI InterfaceCheckout) []Rate {
for _, item := range checkoutI.GetItesm() {
p := item.GetProduct()
}
}
我希望能够测试此 GetRates
方法,而无需模拟 InterfaceCheckout
中的所有方法。
我以为我能够:
- 创建一些更小的接口(interface),仅指定我正在使用的方法
- 将输入转换为这个新界面
传递给一个新的内部方法
func GetRates(checkoutI InterfaceCheckout) []Rate { getRates(checkoutWrapper(checkoutI)) } func getRates(checkoutI checkoutWrapper) []Rate { for _, item := range checkoutI.GetItesm() { p := item.GetProduct() } } // smaller wrapper interfaces type checkoutWrapper interface { GetItems() []InterfaceCartItem }
我遇到的问题是 GetItems
返回的 InterfaceCartItem
在接口(interface)中列出了大约 30 种方法,而我只使用了其中一种 获取产品
。所以我想我可以使用相同的解决方案并使用我需要的一种方法创建一个接口(interface),但是当我尝试更改从 checkoutWrapper@GetItems()
返回的类型时,golang 说 checkoutI
不再满足 checkoutWrapper
接口(interface),因为它返回与 GetItems
不同的类型,这在技术上是正确的...
我试过的代码不起作用
func GetRates(checkoutI InterfaceCheckout) []Rate {
getRates(checkoutWrapper(checkoutI))
}
func getRates(checkoutI InterfaceCheckout) []Rate {
for _, item := range checkoutI.GetItesm() {
p := item.GetProduct()
}
}
// smaller wrapper interfaces
type checkoutWrapper interface {
GetItems() []itemWrapper
}
type itemWrapper interface {
GetProduct() InterfaceProduct
}
那么接口(interface)方法验证是否只进行了一层深度?
最佳答案
只需将您的界面嵌入到假对象中。 例如:
type InterfaceCheckout interface {
GetID() int
GetItems() []InterfaceCartItem
}
type InterfaceCartItem interface {
GetProduct() string
GetID() int
}
type fakeCheckout struct {
InterfaceCheckout
}
func (fakeCheckout) GetItems() []InterfaceCartItem {
return []InterfaceCartItem{fakeItem{}}
}
type fakeItem struct {
InterfaceCartItem
}
func (fakeItem) GetProduct() string {
return "This is the end"
}
func getRates(checkoutI InterfaceCheckout) {
for _, item := range checkoutI.GetItems() {
fmt.Printf("%v\n", item.GetProduct())
}
}
func main() {
fc := fakeCheckout{}
getRates(fc)
}
查看它的运行情况:https://play.golang.org/p/uSFegnZq7S
旁注:避免使用 30 个方法的接口(interface),它们很快就会变得非常麻烦。
编辑
This works, but could explain why embedding the interface in the struct works
在结构中嵌入接口(interface)有点微妙。 The spec提到嵌入接口(interface)会引入它的方法集,因此当你调用它总是编译的方法时。它还引入了接口(interface)类型的 nil 成员。
typ := reflect.TypeOf(fc)
fmt.Printf("+%v\n", typ.Field(0))
你可以看到那里有一个成员:
{Name:InterfaceCheckout PkgPath: Type:main.InterfaceCheckout Tag: Offset:0 Index:[0] Anonymous:true}
它在运行时如何工作?
- 当您调用您的类型覆盖的方法时1 一切正常:您的方法被调用
当您调用一个您未覆盖的方法时,该调用会传递到为 nil 的嵌入对象。这种 panic 很像以下内容:
var ic InterfaceCheckout // nil, just like your embedded type ic.GetItems()
<子>1。类型可以自由覆盖其嵌入类型引入的方法
关于unit-testing - 在 golang 中实现嵌套接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37484935/