[英]Create fake data for rest mapper k8s
I running the following code which works when I'm providing a kubeconfig I was able to get the value of 'gr`我运行以下代码,该代码在提供 kubeconfig 时有效,我能够获得“gr”的值
func (o *ApplyOptions) RestMapper() (meta.RESTMapper, error) {
gr, err := restmapper.GetAPIGroupResources(o.discoveryClient)
if err != nil {
return nil, err
}
mapper := restmapper.NewDiscoveryRESTMapper(gr)
return mapper, nil
}
I 've initiated it with the following code我用下面的代码启动了它
var kubeconfig *string
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
flag.Parse()
// use the current context in kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err.Error())
}
dynamicClient, err := dynamic.NewForConfig(config)
if err != nil {
panic(err.Error())
}
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
if err != nil {
panic(err.Error())
}
applyOptions := apply.NewApplyOptions(dynamicClient, discoveryClient)
if err := applyOptions.Apply(context.Background(), []byte(applyStr)); err != nil {
log.Fatalf("apply error: %v", err)
}
Now I use it for unit test and I got the gr
empty (from restmapper.GetAPIGroupResources(o.discoveryClient)
) above when debug it, , how can I add some fake to make it works also from the test ?现在我将它用于单元测试,并且在调试它时我得到了上面的
gr
空(来自restmapper.GetAPIGroupResources(o.discoveryClient)
),我如何添加一些假以使其在测试中也能正常工作?
var _ = DescribeTable(“test”, func(applyOptions *ApplyOptions, filename string, isExpectedErr bool, expectedErrMsg string) {
applyOptions = ApplyOptions{
discoveryClient: clientset.Discovery() ,
//discoveryClient: &k8sfake.Clientset,
dynamicClient: dynamicfake.NewSimpleDynamicClient(runtime.NewScheme()),
}
// Here I need to initiate some fake data
restmapper, err := applyOptions.RestMapper()
if err != nil {
Fail(err.Error())
}
The error which I got is "k8s.io/apimachinery/pkg/api/ meta.NoKindMatchError "我得到的错误是“ k8s.io/apimachinery/pkg/api/meta.NoKindMatchError ”
update更新
To make it more clear I just trying to create a unit test for this function with kind: deployment
and I got the error above.为了更清楚,我只是尝试使用
kind: deployment
为这个函数创建一个单元测试,我得到了上面的错误。
https://github.com/pytimer/k8sutil/blob/main/apply/apply.go#L119 https://github.com/pytimer/k8sutil/blob/main/apply/apply.go#L119
One possible approach is to abstract the restmapper
away, this will make ApplyOptions
to rely on abstractions, thus you can mock it.一种可能的方法是将
restmapper
抽象出来,这将使ApplyOptions
依赖于抽象,因此您可以模拟它。 Assuming you are unit testing.假设你是单元测试。
We can call it RESTMapperDiscovery
this type will encapsulate the restmapper
capabilities used by ApplyOptions
.我们可以把它叫做
RESTMapperDiscovery
这个类型将封装restmapper
通过使用功能ApplyOptions
。 It is basically a wrapper.它基本上是一个包装器。
type RESTMapperDiscovery struct {}
func (RESTMapperDiscovery) FromGroupResources(cl discovery.DiscoveryInterface) (meta.RESTMapper, error)
FromGroupResources
will concretely implement the code currently part of func (o *ApplyOptions) RestMapper()
. FromGroupResources
将具体实现func (o *ApplyOptions) RestMapper()
当前部分的代码。
To achieve polymorphism we just need an interface.为了实现多态,我们只需要一个接口。
type DiscoveryRESTMapper interface {
FromGroupResources(cl discovery.DiscoveryInterface) (meta.RESTMapper, error)
}
At this stage ApplyOptions
will also depend on DiscoveryRESTMapper
.在这个阶段
ApplyOptions
也将依赖DiscoveryRESTMapper
。
type ApplyOptions struct {
//... other fields
restMapper DiscoveryRESTMapper
}
func (o *ApplyOptions) RestMapper() (meta.RESTMapper, error) {
return o.restMapper.FromGroupResources(o.discoveryClient)
}
When testing, you can use a type which fulfils that interface and will return some fake data.测试时,您可以使用满足该接口的类型并返回一些假数据。
meta.RESTMapper
is an interface as well, thereof your fake data has to implement. 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())
}
This approach relies on composition and interfaces to decouple external dependencies.这种方法依赖于组合和接口来解耦外部依赖。 k8s apis as
restmapper
seems to rely on the same mechanism, thus you could also mock all that from the currently dependencies of ApplyOptions
.作为
restmapper
k8s apis 似乎依赖于相同的机制,因此您也可以从ApplyOptions
的当前依赖项中模拟所有这些。 The trade-off here is your solution being tightly coupled with k8s api, this could result in break changes with restmapper
versions and/or maintenance burden.这里的权衡是您的解决方案与 k8s api 紧密耦合,这可能会导致
restmapper
版本和/或维护负担的中断更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.