去为 gcp compute sdk 创建一个 mock

标签 go kubernetes google-cloud-platform dependency-injection interface

我使用下面的函数,我需要提高它的覆盖率(如果可能到100%),问题是我通常使用interface来处理Go 中的这种情况以及对于这种特定情况不确定如何去做,因为这有点棘手,有什么想法吗?

https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/compute/v1

我使用的没有 interface 所以不确定我该如何模拟它?

import (
    "context"
    "errors"
    "fmt"
    "os"

    compute "cloud.google.com/go/compute/apiv1"
    "google.golang.org/api/iterator"
    "google.golang.org/api/option"
    computev1 "google.golang.org/genproto/googleapis/cloud/compute/v1"
)

func Res(ctx context.Context, project string, region string,vpc string,secret string) error {

    c, err := compute.NewAddressesRESTClient(ctx, option.WithCredentialsFile(secret))

    if err != nil {
        return err
    }

    defer c.Close()
    addrReq := &computev1.ListAddressesRequest{
        Project: project,
        Region:  region,
    }
    it := c.List(ctx, addrReq)

    for {
        resp, err := it.Next()
        if err == iterator.Done {
            break
        }
        if err != nil {
            return err
        }
        if *(resp.Status) != "IN_USE" {
            return ipConverter(*resp.Name, vpc)
        }
    }
    return nil
}

最佳答案

每当我遇到这种情况时,我发现最简单的解决方案是自己创建缺失 接口(interface)。我将这些接口(interface)限制为我正在使用的类型和函数,而不是为整个库编写接口(interface)。然后,在我的代码中,我不接受第三方具体类型,而是接受我的这些类型的接口(interface)。然后我像往常一样使用 gomock 为这些接口(interface)生成模拟。

以下是受您的代码启发的描述性示例。

type RestClient interface {
    List(context.Context, *computev1.ListAddressesRequest) (ListResult, error) // assuming List returns ListResult type.
    Close() error
}

func newRestClient(ctx context.Context, secret string) (RestClient, error) {
    return compute.NewAddressesRESTClient(ctx, option.WithCredentialsFile(secret))
}

func Res(ctx context.Context, project string, region string, vpc string, secret string) error {
    c, err := newRestClient(ctx, secret)
    if err != nil {
        return err
    }

    defer c.Close()
    return res(ctx, project, region, vpc, c)
}

func res(ctx context.Context, project string, region string, vpc string, c RestClient) error {
    addrReq := &computev1.ListAddressesRequest{
        Project: project,
        Region:  region,
    }

    it, err := c.List(ctx, addrReq)
    if err != nil {
        return err
    }

    for {
        resp, err := it.Next()
        if err == iterator.Done {
            break
        }

        if err != nil {
            return err
        }

        if *(resp.Status) != "IN_USE" {
            return ipConverter(*resp.Name, vpc)
        }
    }

    return nil
}

现在您可以通过将模拟 RestClient 注入(inject)内部 res 函数来测试 Res 函数的重要部分。

关于去为 gcp compute sdk 创建一个 mock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72046805/

相关文章:

go - 为什么 RabbitMQ 在不使用时不会保持连接打开?

kubernetes - GKE/Istio : outside world cannot connect to service in private cluster

kubernetes - GAE 从无人机管道激活服务帐户(k8s 上的无人机): No key could be detected

kubernetes - 如何启用 Kubernetes 命令自动完成

python - 是否可以使用 Anaconda 包作为 Google Cloud Functions 的依赖项?

sql - 将数组类型的数据库字段扫描到 Golang 中的数组/slice 中

linux - Go通知macOS

go - 如何将字符串值分配给 GO 中的时间格式?

google-cloud-platform - pyspark错误:: java.io.IOException:方案:gs没有文件系统

laravel - 我应该在 Cloud Run 中删除 Laravel 调度吗?