We can embed an interface inside a struct in Go.
I don’t remember what I was doing at the time—probably writing tests. Then, out of nowhere, I realized I could embed an interface inside a struct and implement only the methods I needed.
This is a neat little trick. I wonder why it isn't more widely used.We embed the LargeExternalClient interface into
mockClient, then implement only MethodF, because
that’s the only method YourClient actually
uses.
If somewhere in the code, some other method on the interface
is in use without our knowledge and we forget to implement it
on the mockClient, the test will panic. This is
actually a good thing: we can add the missing method, and the
test will fail loudly instead of silently passing.
package main
import (
"testing"
)
// somewhere in the imported library.go
type LargeExternalClient interface {
MethodA()
MethodB()
MethodC()
MethodD()
MethodE()
MethodF() int
MethodG()
MethodH()
MethodI()
}
// code.go
type YourClient struct {
cli LargeExternalClient
}
func (y YourClient) Foo() int {
return y.cli.MethodF()
}
// code_test.go
type mockClient struct {
LargeExternalClient
}
func (mockClient) MethodF() int {
return 23
}
func TestYourClient(t *testing.T) {
y := YourClient{
cli: new(mockClient),
}
if y.Foo() != 23 {
t.Fail()
}
}
You can try this example in the Go Playground, and read more about interface embedding at eli.thegreenplace.net.