用于testing使用Docker客户端API的方法的接口错误types错误

我正在重构我写的程序,所以我可以正确地编写testing。 我想testing的第一种方法之一是使用Docker的客户端API来查看Docker主机上是否存在某个图像。

为了能够testing这个方法,我创build了一个匹配client.ImageList的签名的接口:

 type ImageLister interface { ImageList(ctx context.Context, options types.ImageListOptions) ([]types.ImageSummary, error) } 

我还更改了testing方法以将ImageLister作为参数,所以我可以传入特定于我的testing的ImageLister实现。

然而,在我的实际代码中,我将“真正的”Docker客户端传递给要testing的方法,发生以下编译错误:

ImageExists:* client.Client没有实现ImageLister(ImageList方法的错误types)有ImageList(“github.com/docker/docker/vendor/golang.org/x/net/context”.Context,types.ImageListOptions)([ ] types.ImageSummary,错误)想要ImageList(“上下文”.Context,types.ImageListOptions)([] types.ImageSummary,错误)

我该如何解决这个问题? 或者我的方法不好,我应该走不同的路线吗?

编辑:下面的程序重现我遇到的问题。

 package main import ( "context" "github.com/docker/docker/api/types" "github.com/docker/docker/client" ) type ImageLister interface { ImageList(ctx context.Context, options types.ImageListOptions) ([]types.ImageSummary, error) } func main() { client, err := client.NewEnvClient() defer client.Close() ImageExists(context.TODO(), client, "foo") } func ImageExists(ctx context.Context, lister ImageLister, image string) (bool, error) { return true, nil } 

github.com/docker/docker/软件包在“github.com/docker/docker/vendor”目录中有“vendored”它的依赖关系。 虽然vendor/目录中的软件包是通过正常的导入path导入的,但是如果软件包被无意中导入多次,types仍然会按照其完整path进行匹配,以避免不兼容。 因此,在包之间共享types时,两个包都需要从相同的path导入依赖关系。

处理这个问题的方法是正确地供应docker软件包,这意味着将docker使用的软件包移动到最高级供应商目录。 像govendorglide等各种工具可以为你做这件事,现在也有一个“官方”的依赖pipe理工具的工作。

参数types

在接口中声明的方法需要本地typescontext.Context但实现的方法需要Docker的Context 。 这两个实体是完全不同的types,所以ImageLister接口不能用*client.Client实现。

命名import

我相信问题在这里:

想要ImageList(“context”.Context …

这意味着你的本地包名为“上下文”。 由于docker有一个包“上下文”(github.com/docker/docker/vendor/golang.org/x/net/context),这个事实造成了一个命名歧义,并可能导致一些问题。

import声明 :

假设我们已经编译了一个包含package子句包math的包,它导出了函数Sin,并将编译后的包安装在由“lib / math”标识的文件中。 该表说明了如何在各种types的导入声明之后导入包的文件中使用Sin。

 // Import declaration Local name of Sin import "lib/math" // math.Sin import m "lib/math" // m.Sin import . "lib/math" // Sin 

使用命名导入来解决这个歧义:

 import ( ctx "github.com/docker/docker/vendor/golang.org/x/net/context" )