You can embed an interface inside a struct in golang. I discovered it by accident not by reading the manual.
Here is a problem that it solves. Here are many more [1].
You have a dependency on an external library. The library exports a large interface. You want to mock it for testing but then you will have to implement all the methods on it. That can be a lot of work. What if you could implement just the methods you need?
You can do that by embedding interfaces like this. You embed LargeExternalClient
interface into mockClient
, then implement only MethodF
from the interface because
that is the only one YourClient
uses. If somewhere in the code some other method
on the interface is in use without your knowledge and you don't implement it on
mockClient
, you will get a panic. A good thing. Then you just add that one. Test
won't silently pass.
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() } }
Playground link https://play.golang.org/p/YqlBS6oRME8