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

I'm really new to mocking third-party library in go, I'm mocking cloud.google.com/go/storage right now

I'm using mockery. This is my current interface:

//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)
}

and this is how I use it in my function

//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

However, I got this error:

cannot use client (type *"cloud.google.com/go/storage".Client) as type stiface.Client in field value: *"cloud.google.com/go/storage".Client does not implement stiface.Client (wrong type for Bucket method) have Bucket(string) *"cloud.google.com/go/storage".BucketHandle want Bucket(string) stiface.BucketHandle

What have I done wrong here? Thanks!

Edit

here's one example of the code that I want to mock. I'd like to mock on 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
}

The error message is basically saying your stiface.Client defines an interface that *storage.Client does not implement. On first glance your code looks valid however the problem lies in your interface method signatures and because they have outputs as interfaces.

Go makes a difference between the statements:

  • This function returns a BucketHandle
  • and this function returns a *storage.BucketHandle that is a BucketHandle

Try changing your interface to return the *storage.BucketHandle. You can see a more complex example of similar behaviour in the mockery S3API example where the functions return the s3 types, not their own interfaces.