def create_aem_volume(client):
time.sleep(10)
response = client.create_volume(name="foobar", size="100")
return {"VolumeId": response["VolumeId"]}
@patch('time.sleep')
def test_can_create_aem_volume(mock_sleep):
client = boto3.client('ec2') # normal boto3 client
stubber = Stubber(client) # put a wrapper around the client
stubber.add_response('create_volume', {"VolumeId": "a81d2cc238226c8fd333b3ec2b53ada772b386be"}) # mock the response for `create_volume` with a hardcoded value
stubber.activate() # activate it.
response = create_aem_volume(client=client) # pass the client to our function, now any API calls it makes will be mocked
assert response = {"VolumeId": "a81d2cc238226c8fd333b3ec2b53ada772b386be"}
TL;DR: any function using boto3 should accept clients as an argument to facilitate easy mocking