我正在尝试测试一个get_date_from_s3(bucket, table)
使用 pytest 调用的函数。在这个函数中,有一个boto3.client("s3").list_objects_v2()
我想在测试期间模拟的调用,但我似乎无法弄清楚它是如何工作的。
这是我的目录设置:
my_project/
glue/
continuous.py
tests/
glue/
test_continuous.py
conftest.py
conftest.py
该代码continuous.py
将在 AWS 粘合作业中执行,但我正在本地对其进行测试。
my_project/glue/continuous.py
import boto3
def get_date_from_s3(bucket, table):
s3_client = boto3.client("s3")
result = s3_client.list_objects_v2(Bucket=bucket, Prefix="Foo/{}/".format(table))
# [the actual thing I want to test]
latest_date = datetime_date(1, 1, 1)
output = None
for content in result.get("Contents"):
date = key.split("/")
output = [some logic to get the latest date from the file name in s3]
return output
def main(argv):
date = get_date_from_s3(argv[1], argv[2])
if __name__ == "__main__":
main(sys.argv[1:])
my_project/tests/glue/test_continuous.py
这就是我想要的:我想通过模拟 s3_client.list_objects_v2() 并将响应值显式设置为来测试 get_date_from_s3() example_response
。我尝试做类似下面的事情,但它不起作用:
from glue import continuous
import mock
def test_get_date_from_s3(mocker):
example_response = {
"ResponseMetadata": "somethingsomething",
"IsTruncated": False,
"Contents": [
{
"Key": "/year=2021/month=01/day=03/some_file.parquet",
"LastModified": "datetime.datetime(2021, 2, 5, 17, 5, 11, tzinfo=tzlocal())",
...
},
{
"Key": "/year=2021/month=01/day=02/some_file.parquet",
"LastModified": ...,
},
...
]
}
mocker.patch(
'continuous.boto3.client.list_objects_v2',
return_value=example_response
)
expected = "20210102"
actual = get_date_from_s3(bucket, table)
assert actual == expected
笔记
我注意到许多模拟示例都具有作为类的一部分进行测试的功能。因为 Continuous.py 是一项粘合工作,所以我没有找到创建类的实用程序,我只有函数和调用它的 main(),这是一种不好的做法吗?函数之前的模拟装饰器似乎仅用于作为类的一部分的函数。我也读过关于moto
,但似乎无法弄清楚如何在这里应用它。