vendredi 27 mai 2016

fulfilling nested interfaces in golang

I have an Interface that has a lot of submethods.

type InterfaceCheckout interface {
    GetID()    int
    GetItems() []InterfaceCartItem
    // ... then like 30more methods
}

I have a method that only makes use of the GetItems method.

func GetRates(checkoutI InterfaceCheckout) []Rate {
    for _, item := range checkoutI.GetItesm() {
        p := item.GetProduct()
    }
}

I'd like to be able to test this GetRates method without mocking all of the methods in InterfaceCheckout.

I thought I'd be able to:

  1. create some smaller interfaces that specify only the methods I'm making use of
  2. cast the input as this new interface
  3. pass through to a new internal method

    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
    }
    
    

The problem I hit is that the InterfaceCartItem that is returned by GetItems has about 30 methods listed off in the interface, and I'm only using one of them GetProduct. So I thought I could use the same solution and create an interface with the one method I need, but when I try to change the type that is returned from checkoutWrapper@GetItems() golang says that checkoutI no longer satisfies the checkoutWrapper interface because it returns a different type from GetItems which is technically true...

Code that I tried that doesn't work

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
}

so is interface method validation only done one level deep?

Aucun commentaire:

Enregistrer un commentaire