You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单元测试中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 07:42:46