Mock GCP storage bucket blob upload in Python

Simulate uploading a blob to a GCP Storage bucket for testing without hitting the cloud.

Medium Python 3.9+ Aug 9, 2026 Cloud + Python 14 views 0 copies

Python code

63 lines
Python 3.9+
import io
from datetime import datetime
from unittest.mock import MagicMock, patch


class MockBlob:
    """Simulates a GCP storage blob for unit testing."""
    def __init__(self, name):
        self.name = name
        self.uploaded_at = None
        self.content = b""

    def upload_from_file(self, file_obj):
        self.content = file_obj.read()
        self.uploaded_at = datetime.utcnow().isoformat()

    def download_as_string(self):
        return self.content

    def __repr__(self):
        return f"MockBlob(name='{self.name}', size={len(self.content)}, uploaded_at={self.uploaded_at})"


class MockBucket:
    """Simulates a GCP storage bucket."""
    def __init__(self, name):
        self.name = name
        self.blobs = {}

    def blob(self, blob_name):
        if blob_name not in self.blobs:
            self.blobs[blob_name] = MockBlob(blob_name)
        return self.blobs[blob_name]

    def list_blobs(self):
        return list(self.blobs.values())


class MockStorageClient:
    """Simulates the GCP storage client."""
    def __init__(self):
        self.buckets = {}

    def bucket(self, bucket_name):
        if bucket_name not in self.buckets:
            self.buckets[bucket_name] = MockBucket(bucket_name)
        return self.buckets[bucket_name]


def upload_blob(client, bucket_name, blob_name, data: bytes):
    """Upload data as a blob to a mock GCP storage bucket."""
    bucket = client.bucket(bucket_name)
    blob = bucket.blob(blob_name)
    blob.upload_from_file(io.BytesIO(data))
    return blob


if __name__ == "__main__":
    client = MockStorageClient()
    blob = upload_blob(client, "my-bucket", "folder/hello.txt", b"Hello GCP!")
    print(blob)
    print("Downloaded:", blob.download_as_string().decode())
    print("Uploaded at:", blob.uploaded_at)

Output

stdout
MockBlob(name='folder/hello.txt', size=10, uploaded_at=2025-03-25T12:34:56.789012)
Downloaded: Hello GCP!
Uploaded at: 2025-03-25T12:34:56.789012

How it works

The mock classes replicate the essential GCP Storage API surface: client.bucket(), bucket.blob(), and blob.upload_from_file(). Using io.BytesIO wraps bytes so read() returns the original data, and the mock stores it along with an upload timestamp. This lets you test your upload logic without network calls or credentials. The MockBlob also supports download_as_string() to verify content after upload.

Common mistakes

  • Forgetting to wrap bytes in `io.BytesIO` before `upload_from_file`.
  • Using `datetime.utcnow()` instead of timezone-aware `datetime.now(timezone.utc)` (deprecated in 3.12).
  • Not resetting `self.blobs` between tests, causing state leakage.

Variations

  1. Use `unittest.mock.patch` to replace the real `google.cloud.storage.Client` with this mock in your tests.
  2. Add `delete_blob()` and `exists()` methods to the mock for more realistic bucket behavior.

Real-world use cases

  • Unit-testing data-upload logic in a Django or Flask app without creating real GCS buckets.
  • Running offline integration tests for scripts that back up files to GCP Storage.
  • Validating blob naming and content in CI pipelines where cloud credentials aren't available.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Cloud + Python

Related tutorials and quizzes for this topic.