为 Kubernetes 中运行的剩余映射器创建假数据

bre*_*uts 9 azure go kubernetes

我可以在提供 kubeconfig 时运行以下代码。这样做我能够获得以下值gr

\n
func (o *ApplyOptions) RestMapper() (meta.RESTMapper, error) {\n    gr, err := restmapper.GetAPIGroupResources(o.discoveryClient)\n    if err != nil {\n        return nil, err\n    }\n    mapper := restmapper.NewDiscoveryRESTMapper(gr)\n    return mapper, nil\n}\n
Run Code Online (Sandbox Code Playgroud)\n

然后我启动了以下代码:

\n
var kubeconfig *string\n\nkubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")\n\nflag.Parse()\n\n// use the current context in kubeconfig\nconfig, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)\nif err != nil {\n    panic(err.Error())\n}\n\ndynamicClient, err := dynamic.NewForConfig(config)\nif err != nil {\n    panic(err.Error())\n}\ndiscoveryClient, err := discovery.NewDiscoveryClientForConfig(config)\nif err != nil {\n    panic(err.Error())\n}\n\napplyOptions := apply.NewApplyOptions(dynamicClient, discoveryClient)\nif err := applyOptions.Apply(context.Background(), []byte(applyStr)); err != nil {\n    log.Fatalf("apply error: %v", err)\n}\n
Run Code Online (Sandbox Code Playgroud)\n

现在我将它用于单元测试,并且在调试它时gr是空的(来自restmapper.GetAPIGroupResources(o.discoveryClient)上面),\n,我如何添加一些假以使其在测试中也能工作?

\n
var _ = DescribeTable(\xe2\x80\x9ctest\xe2\x80\x9d, func(applyOptions *ApplyOptions, filename string, isExpectedErr bool, expectedErrMsg string) {\n\n\n    applyOptions = ApplyOptions{\n        discoveryClient: clientset.Discovery() ,\n        //discoveryClient: &k8sfake.Clientset,\n        dynamicClient:   dynamicfake.NewSimpleDynamicClient(runtime.NewScheme()),\n\n    }\n\n   // Here I need to initiate some fake data\n    restmapper, err := applyOptions.RestMapper()\n    if err != nil {\n        Fail(err.Error())\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

我得到的错误是"k8s.io/apimachinery/pkg/api/**meta.NoKindMatchError**"

\n

更新

\n

为了明确起见:\n我正在尝试为此函数创建一个单元测试,但kind: deployment出现了上述错误。

\n

小智 -1

一种可能的方法是抽象掉restmapper,这将依赖ApplyOptions于抽象,因此您可以模拟它。假设您正在进行单元测试。

我们可以称其为封装了所使用的功能的RESTMapperDiscovery类型。它基本上是一个包装器。restmapperApplyOptions

type RESTMapperDiscovery struct {}
func (RESTMapperDiscovery) FromGroupResources(cl discovery.DiscoveryInterface) (meta.RESTMapper, error)
Run Code Online (Sandbox Code Playgroud)

FromGroupResources将具体实现当前部分的代码func (o *ApplyOptions) RestMapper()

为了实现多态性,我们只需要一个接口。

type DiscoveryRESTMapper interface {
    FromGroupResources(cl discovery.DiscoveryInterface) (meta.RESTMapper, error)
}
Run Code Online (Sandbox Code Playgroud)

现阶段ApplyOptions也将取决于DiscoveryRESTMapper

type ApplyOptions struct {
    //... other fields
    restMapper DiscoveryRESTMapper
}
func (o *ApplyOptions) RestMapper() (meta.RESTMapper, error) {
    return o.restMapper.FromGroupResources(o.discoveryClient)
}
Run Code Online (Sandbox Code Playgroud)

测试时,您可以使用满足该接口的类型并返回一些假数据。meta.RESTMapper也是一个接口,你的假数据必须实现它。

type mockRESTMapper struct {}
func (mockRESTMapper) FromGroupResources(cl discovery.DiscoveryInterface) (meta.RESTMapper, error) {
    // return the fake meta.RESTMapper
}

applyOptions = &ApplyOptions{
    discoveryClient: clientset.Discovery() ,
    dynamicClient:   dynamicfake.NewSimpleDynamicClient(runtime.NewScheme()),
    restMapper: mockRESTMapper{},

}

// here you have the fake data
restmapper, err := applyOptions.RestMapper()
if err != nil {
    Fail(err.Error())
}
Run Code Online (Sandbox Code Playgroud)

这种方法依赖于组合和接口来解耦外部依赖。k8s apirestmapper似乎依赖于相同的机制,因此您也可以从ApplyOptions. 这里的权衡是您的解决方案与 k8s api 紧密耦合,这可能会导致restmapper版本和/或维护负担的重大更改。