safir.testing.gcs.patch_google_storage(*, expected_expiration=None, path=None, bucket_name=None)

Replace the Google Cloud Storage API with a mock class.

This function will replace the API with a mock object. It only supports bucket requests, the buckets only support blob requests, and the blobs only support requests for signed URLs. The value of the signed URL will be where blob is the name of the blob.

  • expected_expiration (timedelta | None, default: None) – The expiration that should be requested in a call to generate_signed_url on an underlying blob. A non-matching call will produce an assertion failure.

  • path (Path | None, default: None) – Root of the file path for blobs, if given. If not given, a simpler mock blob will be used that only supports generate_signed_url.

  • bucket_name (str | None, default: None) – If set, all requests for a bucket with a name other than the one provided will produce assertion failures.


MockStorageClient – The mock Google Cloud Storage API client (although this is rarely needed by the caller).

Return type:



This function also mocks out google.auth.default and the impersonated credentials structure so that this mock can be used with applications that use workload identity.

To use this mock successfully, you must not import Client (or Credentials) directly into the local namespace, or it will not be correctly patched. Instead, use:

from import storage

and then use storage.Client and so forth. Do the same with q`google.auth.impersonated_credentials.Credentials``.


Normally this should be called from a fixture in tests/ such as the following:

from datetime import timedelta

from safir.testing.gcs import MockStorageClient, patch_google_storage

def mock_gcs() -> Iterator[MockStorageClient]:
    yield from patch_gcs(