如何在golang中模拟GCP的存储?

时间:2019-04-26 00:32:38

标签: go mocking

我真的对模拟第三方库很陌生,我现在在模拟cloud.google.com/go/storage

我正在使用mockery。这是我当前的界面:

//Client storage client
type Client interface {
    Bucket(name string) BucketHandle
    Buckets(ctx context.Context, projectID string) BucketIterator
}

//BucketHandle storage's BucketHandle
type BucketHandle interface {
    Attrs(context.Context) (*storage.BucketAttrs, error)
    Objects(context.Context, *storage.Query) ObjectIterator
}

//ObjectIterator storage's ObjectIterator
type ObjectIterator interface {
    Next() (*storage.ObjectAttrs, error)
}

//BucketIterator storage's BucketIterator
type BucketIterator interface {
    Next() (*storage.BucketAttrs, error)
}

这就是我在函数中使用它的方式

//Runner runner for this module
type Runner struct {
    StorageClient stiface.Client
}

.... function
   //get storage client
    client, err := storage.NewClient(ctx)
    if err != nil {
        return err
    }

    runner := Runner{
        StorageClient: client,
    }
.... rest of functions

但是,我遇到了这个错误:

  

不能在字段值中使用客户端(类型*“ cloud.google.com/go/storage” .Client)作为stiface.Client类型:       *“ cloud.google.com/go/storage”。客户端未实现stiface.Client(Bucket方法的类型错误)           具有存储桶(字符串)*“ cloud.google.com/go/storage” .BucketHandle           想要Bucket(string)stiface.BucketHandle

我在这里做错了什么?谢谢!

修改

这是我要模拟的代码的一个示例。我想模拟bucketIterator.Next()

//GetBuckets get list of buckets
func GetBuckets(ctx context.Context, client *storage.Client, projectName string) []checker.Resource {
    //Get bucket iterator based on a project
    bucketIterator := client.Buckets(ctx, projectName)
    //iterate over the buckets and store bucket details
    buckets := make([]checker.Resource, 0)
    for bucket, done := bucketIterator.Next(); done == nil; bucket, done = bucketIterator.Next() {
        buckets = append(buckets, checker.Resource{
            Name: bucket.Name,
            Type: "Bucket",
        })
    }
    return buckets
}

2 个答案:

答案 0 :(得分:1)

该错误消息基本上是说您的stiface.Client定义了*storage.Client未实现的接口。乍一看,您的代码看起来有效,但是问题出在接口方法签名上,因为它们具有输出作为接口。

Go在语句之间有所不同:

  • 此函数返回一个BucketHandle
  • 此函数返回一个*storage.BucketHandle的{​​{1}}

尝试更改界面以返回BucketHandle。您可以在mockery S3API example中看到类似行为的更复杂示例,其中函数返回*storage.BucketHandle类型,而不是它们自己的接口。

答案 1 :(得分:1)

经过反复试验,使用stiface的方法如下

如果您需要模拟=SUMPRODUCT( MMULT(--(TRANSPOSE(List2)=B:B),INDEX(1+0*MUNIT(COUNTA(List2)),0,1)), MMULT(--(TRANSPOSE(List1)=A:A),INDEX(1+0*MUNIT(COUNTA(List1)),0,1))) ,则可以创建模拟为

stiface.BucketIterator

并相应地模拟type mockBucketIterator struct { stiface.BucketIterator }

Next

您可以使用相同的方法进行模拟,直到func (m mockBucketIterator) Next() (*storage.BucketAttrs, error) { // mocks that you need this to return return } 为止,并将模拟客户端提供给测试。

作为参考,是我测试中的完整示例:

satiface.Client

然后是对象迭代器,也将返回模拟的迭代器

type clientMock struct {
    stiface.Client
}
type bucketMock struct {
    stiface.BucketHandle
}
type objectItMock struct {
    stiface.ObjectIterator
    i    int
    next []storage.ObjectAttrs
}

func (m clientMock) Bucket(name string) stiface.BucketHandle {
    return bucketMock{}
}