【问题标题】:How to write simple tests for client-go using a fake client?如何使用假客户端为客户端编写简单的测试?
【发布时间】:2019-09-07 12:02:31
【问题描述】:

问题

我正在寻找正确的方法来测试下面的代码,但我找不到任何示例,我该怎么做。只有main_test.go,但它缺少 main.go,对我来说,如何使用它并不明显。 我也浏览了 Github issues 但我找不到任何有用的东西。

功能:

import (
  "fmt"
  "k8s.io/api/core/v1"
  metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  fake "k8s.io/client-go/kubernetes/fake"
  "time"
)

func GetNamespaceCreationTime(namespace string) int64 {
    config, err := rest.InClusterConfig()
    if err != nil {
        panic(err.Error())
    }
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err.Error())
    }

    ns, err := clientset.CoreV1().Namespaces().Get(namespace, metav1.GetOptions{})
    if err != nil {
        panic(err.Error())
    }
    fmt.Printf("%v \n", ns.CreationTimestamp)
    return (ns.GetCreationTimestamp().Unix())
}

测试:

我认为我的测试应该如下所示,但是如何使用config := fake.NewSimpleClientset(),我应该将它传递给GetNamespaceCreationTime 函数吗?

func TestGetNamespaceCreationTime(t *testing.T) {
  config := fake.NewSimpleClientset()
  got := GetNamespaceCreationTime("default")
  want := int64(1257894000)

  nsMock := config.CoreV1().Namespaces()
  nsMock.Create(&v1.Namespace{
    ObjectMeta: metav1.ObjectMeta{
      Name:              "default",
      CreationTimestamp: metav1.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
    },
  })

  if got != want {
    t.Errorf("got %q want %q", got, want)
  }

【问题讨论】:

    标签: go client-go


    【解决方案1】:

    您需要将初始化部分移到 GetNamespaceCreationTime 函数之外。您可以将 kubernetes.Interface 作为参数传递给该函数。

        import (
          "fmt"
          "k8s.io/api/core/v1"
          metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
          fake "k8s.io/client-go/kubernetes/fake"
          "k8s.io/client-go/kubernetes"
          "time"
        )
    
    var getInclusterConfigFunc = rest.InClusterConfig
    var getNewKubeClientFunc = dynamic.NewForConfig
       
        
        func GetNamespaceCreationTime(kubeClient kubernetes.Interface, namespace string) int64 {
        
            ns, err := kubeClient.CoreV1().Namespaces().Get(namespace, metav1.GetOptions{})
            if err != nil {
                panic(err.Error())
            }
            fmt.Printf("%v \n", ns.CreationTimestamp)
            return (ns.GetCreationTimestamp().Unix())
        }
        
        func GetClientSet() kubernetes.Interface {
          config, err := getInclusterConfigFunc()
          if err != nil {
            log.Warnf("Could not get in-cluster config: %s", err)
            return nil, err
          }
    
          client, err := getNewKubeClientFunc(config)
          if err != nil {
            log.Warnf("Could not connect to in-cluster API server: %s", err)
            return nil, err
          }
    
          return client, err
        }
    

    然后你的测试函数可以实例化假客户端并调用方法。

        func TestGetNamespaceCreationTime(t *testing.T) {
          kubeClient := fake.NewSimpleClientset()
          got := GetNamespaceCreationTime(kubeClient, "default")
          want := int64(1257894000)
        
          nsMock := config.CoreV1().Namespaces()
          nsMock.Create(&v1.Namespace{
            ObjectMeta: metav1.ObjectMeta{
              Name:              "default",
              CreationTimestamp: metav1.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
            },
          })
        
          if got != want {
            t.Errorf("got %q want %q", got, want)
          }
    
    func fakeGetInclusterConfig() (*rest.Config, error) {
        return nil, nil
    }
    
    func fakeGetInclusterConfigWithError() (*rest.Config, error) {
        return nil, errors.New("fake error getting in-cluster config")
    }
    
    func TestGetInclusterKubeClient(t *testing.T) {
        origGetInclusterConfig := getInclusterConfigFunc
        getInclusterConfigFunc = fakeGetInclusterConfig
        origGetNewKubeClient := getNewKubeClientFunc
        getNewKubeClientFunc = fakeGetNewKubeClient
    
        defer func() {
            getInclusterConfigFunc = origGetInclusterConfig
            getNewKubeClientFunc = origGetNewKubeClient
        }()
    
        client, err := GetClientSet()
        assert.Nil(t, client, "Client is not nil")
        assert.Nil(t, err, "error is not nil")
    }
    
    func TestGetInclusterKubeClient_ConfigError(t *testing.T) {
        origGetInclusterConfig := getInclusterConfigFunc
        getInclusterConfigFunc = fakeGetInclusterConfigWithError
    
        defer func() {
            getInclusterConfigFunc = origGetInclusterConfig
        }()
    
        client, err := GetInclusterKubeClient()
        assert.Nil(t, client, "Client is not nil")
        assert.NotNil(t, err, "error is nil")
    }
    

    【讨论】:

    • 只是问一下,你现在将如何测试GetClientSet
    • 这就是纯函数式编程派上用场的地方。而不是调用 rest.InClusterConfig() 您可以将其分配给一个变量,并在测试中您可以覆盖它。我编辑了答案以反映它。这同样适用于 kubernetes.NewForConfig。
    • @AlexanderJeyaraj 示例测试文件是否完整?我找不到 func fakeGetNewKubeClient
    • @AlexanderJeyaraj 您添加的代码不可编译。 TestGetNamespaceCreationTime 函数缺少右括号和 config 包/变量的定义。
    猜你喜欢
    • 1970-01-01
    • 2018-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多