I'm trying refactor some code to use dependency injection for the Docker client library I use in my code. I created an interface with the method I want to be able to mock
type DockerClient interface {
Ping(context.Context) (types.Ping, error)
}
func NewDockerUtil() (*DockerUtil, error) {
var dockerClient *DockerClient
var err error
dockerClient, err = client.NewEnvClient() //Reports incompatible types in binary and unary expressions.
if err != nil {
return nil, err
}
return &DockerUtil{
Client: dockerClient,
}, nil
}
type DockerUtil struct{
Client *DockerClient
}
But when I try to assign it I get Reports incompatible types in binary and unary expressions.
What exactly do I need to change?
Let's start with using interface{}
, when you define interface don't use pointer definition, good read here.
type DockerUtil struct{
Client DockerClient
}
And moby Client implements lot of methods and you would like to do interface
for selective methods.
Right way to do is via Type assertion. Good read Effective Go - Type assertions and Spec - Type assertion.
Note: try this code, I don't have docker env in my machine to test.
func NewDockerUtil() (*DockerUtil, error) {
dockerClient, err := client.NewEnvClient()
if err != nil {
return nil, err
}
return &DockerUtil{
Client: dockerClient.(DockerClient),
}, nil
}
Note:
Using DockerUtil.Client
, you can call only Ping
method since your interface DockerClient
has definition of Ping
method.
If you would like to call all the methods supported by client.Client
later on then you have to do type assertion-
dockerClient := DockerUtil.Client.(*client.Client)