How do I use simulation tests boto3 resource download file to throw a 404 error?
I want to test the download_file
of s3 resources
This is the code I’m going to test
def logfile_downloader():
s3 = boto3.resource('s3')
bucket = s3. Bucket(bucket)
for object in bucket.objects.filter(Prefix='logs/access_2018'):
try:
bucket.download_file(object.key, 'logs/' + save_path + '/' + object.key.split('/')[-1])
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code'] == "404":
click.echo(click.style("The object does not exist.", bg="white", fg="red"))
else:
raise
When I tested with python mock, it passed:
@mock.patch('boto3.resource')
def test_log_downloader(mock_resource):
logfinder._log_downloader()
assert mock_resource.called
However, coverage is not 100 percent because botocore.exceptions.ClientError
is not tested
So I created a test
@mock.patch('s3. Bucket.download_file')
def test_log_downloader_404(mock_download_file):
mock_download_file.return_value = 404
logfinder.log_downloader()
assert mock_download_file.called
But it failed
ModuleNotFoundError: No module named 's3'
I think mock throws an error when running the download_file
function.
I found download_file
documented here:
http://boto3.readthedocs.io/en/latest/guide/s3-example-download-file.html#more-info
But in the test, I can’t import the s3 module
Solution
S3
is not a module, boto3
is. I want to simulate a 500 response botocore.exceptions.ClientError
object like you. Here’s how I did it (I updated my code to match yours because they’re very similar):
import botocore
def test_log_downloader_500():
with mock.patch('boto3.s3.transfer.S3Transfer.download_file') as download_file:
error_response = {'Error': {'Code': '500'}}
side_effect = botocore.errorfactory.ClientError(error_response, 'unexpected')
download_file.side_effect = side_effect
with pytest.raises(botocore.errorfactory.ClientError):
logfinder.log_downloader()
This will cover the else raise
section. Simply do the same for 404 errors by replacing the values above, and you’ll cover the 404 condition ????