使用 moto 和 boto3 上传测试文件
upload a test file using moto and boto3
我想测试对从 aws 导入的文件进行测试。
我使用 moto 模拟 s3,以免弄乱实际数据。但是,现在 aws 似乎是空的,因此我决定在模拟 s3 上上传一些测试文件。我该怎么做?
这是我的设置,
Conftest.py:
@pytest.fixture(scope='function')
def aws_credentials():
"""Mocked AWS Credentials for moto."""
os.environ['AWS_ACCESS_KEY_ID'] = 'testing'
os.environ['AWS_SECRET_ACCESS_KEY'] = 'testing'
os.environ['AWS_SECURITY_TOKEN'] = 'testing'
os.environ['AWS_SESSION_TOKEN'] = 'testing'
@pytest.fixture(scope='function')
def s3(aws_credentials):
with mock_s3():
yield boto3.client('s3', region_name='us-east-1')
测试文件:
class TestLoadRecommendations:
@pytest.fixture(autouse=True)
def _setup(self, s3):
self.bucket = s3.create_bucket(Bucket=settings.SERVER_DATA_S3_BUCKET)
self.bucket.upload_file("tmp/recommendations-2021-04-13T17_28_06.csv", "tmp/recommendations-2021-04-13T17_28_06.csv")
然而,上传它会引发错误 TypeError: expected string or bytes-like object
但我确定我使用了不正确的文件上传命令。
有人可以帮忙吗?谢谢!
有多种方法可以将文件上传到 S3。您的示例结合了 S3 资源和 S3 客户端方法,这将不起作用。
示例见以下代码:
- S3 客户端 - upload_fileobj
- S3-资源 - upload_file
- 桶资源 - upload_file
三条路通罗马
import boto3
from moto import mock_s3
BUCKET_NAME = "mybucket"
FILE_NAME = "red.jpg"
FILE_LOCATION = FILE_NAME
@mock_s3
def test_client():
create_bucket()
s3 = boto3.client('s3')
with open(FILE_LOCATION, 'rb') as data:
s3.upload_fileobj(data, BUCKET_NAME, FILE_NAME)
verify_upload()
@mock_s3
def test_resource():
s3_resource, _ = create_bucket()
s3_resource.meta.client.upload_file(FILE_LOCATION, BUCKET_NAME, FILE_NAME)
#
verify_upload()
@mock_s3
def test_bucket_resource():
_, bucket = create_bucket()
bucket.upload_file(FILE_LOCATION, FILE_NAME)
#
verify_upload()
def verify_upload():
client = boto3.client("s3")
resp = client.get_object(Bucket=BUCKET_NAME, Key=FILE_NAME)
content_length = resp["ResponseMetadata"]["HTTPHeaders"]["content-length"]
print("Content-Length: {}".format(content_length))
def create_bucket():
s3 = boto3.resource("s3")
bucket = s3.create_bucket(Bucket=BUCKET_NAME)
return s3, bucket
注意:我正在使用装饰器,但这些示例在使用 Moto fixtures 时效果完全相同。
我想测试对从 aws 导入的文件进行测试。 我使用 moto 模拟 s3,以免弄乱实际数据。但是,现在 aws 似乎是空的,因此我决定在模拟 s3 上上传一些测试文件。我该怎么做?
这是我的设置,
Conftest.py:
@pytest.fixture(scope='function')
def aws_credentials():
"""Mocked AWS Credentials for moto."""
os.environ['AWS_ACCESS_KEY_ID'] = 'testing'
os.environ['AWS_SECRET_ACCESS_KEY'] = 'testing'
os.environ['AWS_SECURITY_TOKEN'] = 'testing'
os.environ['AWS_SESSION_TOKEN'] = 'testing'
@pytest.fixture(scope='function')
def s3(aws_credentials):
with mock_s3():
yield boto3.client('s3', region_name='us-east-1')
测试文件:
class TestLoadRecommendations:
@pytest.fixture(autouse=True)
def _setup(self, s3):
self.bucket = s3.create_bucket(Bucket=settings.SERVER_DATA_S3_BUCKET)
self.bucket.upload_file("tmp/recommendations-2021-04-13T17_28_06.csv", "tmp/recommendations-2021-04-13T17_28_06.csv")
然而,上传它会引发错误 TypeError: expected string or bytes-like object
但我确定我使用了不正确的文件上传命令。
有人可以帮忙吗?谢谢!
有多种方法可以将文件上传到 S3。您的示例结合了 S3 资源和 S3 客户端方法,这将不起作用。
示例见以下代码:
- S3 客户端 - upload_fileobj
- S3-资源 - upload_file
- 桶资源 - upload_file
三条路通罗马
import boto3
from moto import mock_s3
BUCKET_NAME = "mybucket"
FILE_NAME = "red.jpg"
FILE_LOCATION = FILE_NAME
@mock_s3
def test_client():
create_bucket()
s3 = boto3.client('s3')
with open(FILE_LOCATION, 'rb') as data:
s3.upload_fileobj(data, BUCKET_NAME, FILE_NAME)
verify_upload()
@mock_s3
def test_resource():
s3_resource, _ = create_bucket()
s3_resource.meta.client.upload_file(FILE_LOCATION, BUCKET_NAME, FILE_NAME)
#
verify_upload()
@mock_s3
def test_bucket_resource():
_, bucket = create_bucket()
bucket.upload_file(FILE_LOCATION, FILE_NAME)
#
verify_upload()
def verify_upload():
client = boto3.client("s3")
resp = client.get_object(Bucket=BUCKET_NAME, Key=FILE_NAME)
content_length = resp["ResponseMetadata"]["HTTPHeaders"]["content-length"]
print("Content-Length: {}".format(content_length))
def create_bucket():
s3 = boto3.resource("s3")
bucket = s3.create_bucket(Bucket=BUCKET_NAME)
return s3, bucket
注意:我正在使用装饰器,但这些示例在使用 Moto fixtures 时效果完全相同。