Reputation: 10329
I've implemented a wrapper for the Docker ApiClient like so
type DockerClient struct {
cli client.APIClient
}
I've also defined my own interface for interacting with Docker like so
type Dockerer interface {
Init() error
CreateContainer(ctx context.Context, imageName string) (string, error)
RunCommand(ctx context.Context, containerId string, command string) (string, int, error)
StopContainer(ctx context.Context, containerId string) error
}
DockerClient
implements the functions in the Dockerer
interface like so:
func (d *DockerClient) Init() error {
//...
}
func (d *DockerClient) CreateContainer(ctx context.Context, imageName string) (string, error) {
//...
}
func (d *DockerClient) RunCommand(ctx context.Context, containerId string, command string) (string, int, error) {
//...
}
func (d *DockerClient) StopContainer(ctx context.Context, containerId string) error {
//...
}
This has made it easy to test the components of my code that need to interface with Docker because I can generate a mock for my Dockerer
interface and dependency inject that mock.
However, now I'd like to write tests for the actual implementation of the DockerClient
wrapper. It seems like no mocks are provided for ApiClient
by the docker package. Is there a canonical pattern for writing tests when the package I need to use doesn't provide mocks? Is there a way to get mockery to generate mocks for library interfaces?
Upvotes: 3
Views: 1365
Reputation: 37172
client.APIClient is an interface. You can embed that interface in a struct. Yes you can do this. You can embed interface inside struct. Then you selectively implement methods that you need for test. This way you don't have to implement every single method from the interface. It will impractical to implement all the methods that client.APIClient
provides because it embeds interface that embeds whole lot of interfaces. See.
Like this,
type mockCli struct{
client.APIClient
}
func (mockCli) ClientVersion() string {
return "5"
}
func TestA(t *testing.T) {
dc := &DockerClient{
cli: new(mockCli),
}
...
dc.Init()
// This will print "5" if your Init has
// fmt.Println(d.cli.ClientVersion())) somewhere.
// If you call any other method of cli, you get panic.
// A good thing. It will inform you that you are using
// some method that you don't have on mockCli. You
// just add it then.
}
Upvotes: 4