How to mock google cloud api on python
Mock from python is really useful, when comes to testing. I have being in projects that the CI actually used the Google Cloud to run tests, a waste of money. Let’s make some examples on how mock the google cloud api and how to learn the most important topic related to mock: THE FUCKING PATH (spent so many time with this):
Let’s imagine this situation: you create a separated file to handle google-cloud functions, and your app import it.
# storage.py
from google.cloud.storage import Client
def upload_file(filename, content, bucket):
# get client and bucket
bucket = Client().get_bucket(bucket)
# upload file
blob = bucket.blob(filename)
blob.upload_from_string(content)
---------
#app.py
from storage import upload_file
def upload_report(reportContent):
upload_file("report", reportContent, "bucket")
Let’s mock it from test_app.py:
import mock
from app import upload_report
@mock.patch("storage.Client")
def test_upload(client):
# run function just recording interaction trought mock
upload_report("")
# assert bucket was called with the passed string
bucket = client().get_bucket
bucket.assert_called_with("bucket")
# assert blob and upload were called with expected params
blob = bucket().blob
blob.assert_called_with("report")
blob().upload_from_string.assert_called_with("")
Keep in mind that when mocking, you need to target the environment that things are running. I usually try to follow the file that I’m using and then I choose the import.
Let’s inspect the Mock in real time with PDB:
> /private/tmp/storage.py(3)upload_file()
-> def upload_file(filename, content, bucket):
(Pdb) n
> /private/tmp/storage.py(6)upload_file()
-> bucket = Client().get_bucket(bucket)
(Pdb) Client
<MagicMock id='4362852112'>
(Pdb) n
> /private/tmp/storage.py(9)upload_file()
-> blob = bucket.blob(filename)
(Pdb) bucket
<MagicMock name='mock().get_bucket()' id='4395823248'>
(Pdb) n
> /private/tmp/storage.py(10)upload_file()
-> blob.upload_from_string(content)
(Pdb) blob
<MagicMock name='mock().get_bucket().blob()' id='4395913296'>
If we added side-effect or return_value properties, we could see here at the debugging.