我有一个包含很多子方法的接口。
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
方法。
我以为我能够:
传递给新的内部方法
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
}
我遇到的问题是InterfaceCartItem
返回的GetItems
在界面中列出了约30种方法,而我只使用其中一种GetProduct
。所以我想我可以使用相同的解决方案并使用我需要的一个方法创建一个接口,但是当我尝试更改从checkoutWrapper@GetItems()
返回的类型时,golang说checkoutI
不再满足{ {1}}接口,因为它从checkoutWrapper
返回不同的类型,这在技术上是正确的......
我尝试的代码不起作用
GetItems
接口方法验证只做了一层深度吗?
答案 0 :(得分:6)
将您的界面嵌入虚假对象中。 例如:
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种方法的界面,它们会很快变得非常麻烦。
这有效,但可以解释为什么在结构中嵌入接口
在结构中嵌入接口有点微妙。 The spec提到嵌入接口会引入其方法集,因此当您调用它总是编译的方法时。它还引入了接口类型的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}
它如何在运行时工作?
当你调用一个你不会覆盖的方法时,调用将进入嵌入对象,即nil。这很像下面的恐慌:
var ic InterfaceCheckout // nil, just like your embedded type
ic.GetItems()
<子> 1。类型可以自由覆盖其嵌入类型
带来的方法