Question: I'm writing an appengine app in Go that uses [Google cloud storage](https://godoc.org/cloud.google.com/go/storage).

For example, my "reading" code looks like:

```
client, err := storage.NewClient(ctx)
if err != nil {
    return nil, err
}
defer func() {
    if err := client.Close(); err != nil {
        panic(err)
    }
}()
r, err := client.Bucket(BucketName).Object(id).NewReader(ctx)
if err != nil {
    return nil, err
}
defer r.Close()
return ioutil.ReadAll(r)

```

... where `ctx` is a context from appengine.

When I run this code in a unit test (using `aetest`), it actually sends requests to my cloud storage; I'd like to run this hermetically instead, similar to how `aetest` allows fake datastore calls.

(Possibly related [question](https://stackoverflow.com/questions/32613897/unit-testing-googles-cloud-storage-api), but it deals with python, and the linked [github issue](https://github.com/GoogleCloudPlatform/appengine-gcs-client/issues/21) indicates it's solved in a python-specific way).

How can I do this?

Answer: 
One approach, also suggested [here](https://stackoverflow.com/questions/19167970/mock-functions-in-go) is to allow your GCS client to have its downloader swapped out for a stub while unit testing. First, define an interface that matches how you use the Google Cloud Storage library, and then reimplement it with fake data in your unit tests.

Something like this:

```
type StorageClient interface {
  Bucket(string) Bucket  // ... and so on, matching the Google library
}

type Storage struct {
  client StorageClient
}

// New creates a new Storage client
// This is the function you use in your app
func New() Storage {
  return NewWithClient(&realGoogleClient{}) // provide real implementation here as argument
}

// NewWithClient creates a new Storage client with a custom implementation
// This is the function you use in your unit tests
func NewWithClient(client StorageClient) {
  return Storage{
    client: client,
  }
}

```

It can be a lot of boilerplate to mock entire 3rd party APIs, so maybe you'll be able to make it easier by generating some of those mocks with [golang/mock](https://github.com/golang/mock) or [mockery](https://github.com/vektra/mockery).
I would advice you reduce the mocks as much as possible you might need to use an hermetic approach to make it almost similar to the real thing .
<https://testing.googleblog.com/2012/10/hermetic-servers.html>