如何在单元测试中Mock S3文件的last_modified属性?
给不同S3文件设置独立的Last-Modified时间戳进行单元测试
方法1:直接修改Moto的内部存储元数据
Moto模拟S3时,会将桶和文件的元数据存在内部backend对象里。你可以直接定位到目标文件的元数据,手动修改last_modified属性,实现不同文件的时间戳差异化。
示例代码:
import boto3 from moto import mock_s3 from datetime import datetime, timezone @mock_s3 def test_s3_file_last_modified(): # 初始化S3客户端和测试桶 s3 = boto3.client("s3", region_name="us-east-1") bucket_name = "test-bucket" s3.create_bucket(Bucket=bucket_name) # 上传两个测试文件 s3.put_object(Bucket=bucket_name, Key="file1.txt", Body=b"content1") s3.put_object(Bucket=bucket_name, Key="file2.txt", Body=b"content2") # 获取Moto的S3 backend,定位目标文件 backend = s3._endpoint._url_builder._endpoint_prefix_to_factory["s3"]._backend bucket = backend.buckets[bucket_name] file1 = bucket.keys["file1.txt"] file2 = bucket.keys["file2.txt"] # 设置不同的Last-Modified时间 file1.last_modified = datetime(2024, 1, 1, 10, 0, 0, tzinfo=timezone.utc) file2.last_modified = datetime(2024, 1, 1, 14, 0, 0, tzinfo=timezone.utc) # 验证时间戳 resp1 = s3.head_object(Bucket=bucket_name, Key="file1.txt") resp2 = s3.head_object(Bucket=bucket_name, Key="file2.txt") assert resp1["LastModified"] == datetime(2024, 1, 1, 10, 0, 0, tzinfo=timezone.utc) assert resp2["LastModified"] == datetime(2024, 1, 1, 14, 0, 0, tzinfo=timezone.utc) assert resp1["LastModified"] < resp2["LastModified"]
注意:这种方法依赖Moto的内部实现,不同版本的Moto可能调整backend结构,升级时需要验证兼容性。
方法2:分阶段冻结时间上传文件
借助freezegun库,在上传每个文件时临时冻结到指定时间,上传完成后恢复时间,这样每个文件的last_modified会自动对应冻结的时间点。
示例代码:
import boto3 from moto import mock_s3 from freezegun import freeze_time from datetime import datetime, timezone @mock_s3 def test_s3_file_last_modified_with_freezer(): s3 = boto3.client("s3", region_name="us-east-1") bucket_name = "test-bucket" s3.create_bucket(Bucket=bucket_name) # 冻结到第一个时间点,上传file1 with freeze_time("2024-01-01 10:00:00 UTC"): s3.put_object(Bucket=bucket_name, Key="file1.txt", Body=b"content1") # 冻结到第二个时间点,上传file2 with freeze_time("2024-01-01 14:00:00 UTC"): s3.put_object(Bucket=bucket_name, Key="file2.txt", Body=b"content2") # 验证时间戳 resp1 = s3.head_object(Bucket=bucket_name, Key="file1.txt") resp2 = s3.head_object(Bucket=bucket_name, Key="file2.txt") assert resp1["LastModified"] == datetime(2024, 1, 1, 10, 0, 0, tzinfo=timezone.utc) assert resp2["LastModified"] == datetime(2024, 1, 1, 14, 0, 0, tzinfo=timezone.utc) assert resp1["LastModified"] < resp2["LastModified"]
这种方法不依赖Moto内部结构,兼容性更好,适合长期维护的测试用例。
内容的提问来源于stack exchange,提问作者Sundeep
相关产品推荐
相关产品推荐

