如何使用mock进行boto3资源下载文件404error测试?

时间:2018-03-15 01:59:55

标签: python boto3 python-mock

我想测试s3资源download_file:)

这是我的代码

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

当我使用python mock测试时,测试已通过

@mock.patch('boto3.resource')
    def test_log_downloader(mock_resource):
    logfinder._log_downloader()
    assert mock_resource.called

但是,覆盖率不是100%,,,因为未测试botocore.exceptions.ClientError

所以我创建了一个测试

@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

但失败了

ModuleNotFoundError: No module named 's3'

我认为在运行download_file函数时,mock会引发错误,

所以我找到了download_file路径http://boto3.readthedocs.io/en/latest/guide/s3-example-download-file.html#more-info

但是测试无法导入s3模块

请有人告诉我一些建议,谢谢

1 个答案:

答案 0 :(得分:1)

concern不是模块,s3是模块。我想做与您相同的事情,嘲笑500个响应boto3对象。这是我的操作方式(我更新了代码以使其与您的代码相匹配,因为它非常相似):

botocore.exceptions.ClientError

这将涵盖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() 部分。通过替换上面的值,对404错误执行相同的操作,即可涵盖404条件