我正在为一个简单的函数编写单元测试,该函数将字节写入s3:
import s3fs
def write_bytes_as_csv_to_s3(payload, bucket, key):
fs = s3fs.S3FileSystem()
fname = f"{bucket}/{key}"
print(f"writing {len(payload)} bytes to {fname}")
with fs.open(fname, "wb") as f:
f.write(payload)
return fname
def test_write_bytes_as_csv_to_s3(mocker):
s3fs_mock = mocker.patch('s3fs.S3FileSystem')
open_mock = mocker.MagicMock()
# write_mock = mocker.MagicMock()
# open_mock.write.return_value = write_mock
s3fs_mock.open.invoke.return_value = open_mock
result = write_bytes_as_csv_to_s3('awesome'.encode(), 'random', 'key')
assert result == 'random/key'
s3fs_mock.assert_called_once()
open_mock.assert_called_once()
# write_mock.assert_called_once()
如何检查方法open
和write
是否已被调用一次?不确定如何设置mocker
来解决我的情况。
答案 0 :(得分:0)
您上面编写的单元测试非常完美,并且涵盖了您要测试的方法的所有功能。
在pytest中,有一项功能可以获取unittest覆盖率报告,该报告将显示unittest覆盖的行。
请安装pytest插件html-report(如果未安装)并执行以下文档:-
py.test --cov=<filename to cover: unittest> --cov-report=html <testfile>
之后,您可能会在 htmlconv /目录的当前位置 o / r中找到一个html文件。然后,您可以轻松地了解覆盖的范围以及单元测试覆盖率的百分比。
答案 1 :(得分:0)
问题在于了解每个模拟的创建方式以及模拟的内容。例如,mocker.patch('s3fs.S3FileSystem')
返回s3fs.S3FileSystem
的模拟,而不是调用s3fs.S3FileSystem()
返回的实例。然后要模拟with fs.open(fname, "wb") as f
,您需要模拟__enter__
dunder方法返回的内容。希望下面的代码可以使关系清楚:
def test_write_bytes_as_csv_to_s3(mocker):
# Mock of the open's context manager
open_cm_mock = mocker.MagicMock()
# Mock of the object returned by fs.open()
open_mock = mocker.MagicMock()
open_mock.__enter__.return_value = open_cm_mock
# Mock of the new instance returned by s3fs.S3FileSystem()
fs_mock = mocker.MagicMock()
fs_mock.open.return_value = open_mock
# Patching of s3fs.S3FileSystem
mocker.patch('s3fs.S3FileSystem').return_value = fs_mock
# Running the tested code and making assertions
result = write_bytes_as_csv_to_s3('awesome'.encode(), 'random', 'key')
assert result == 'random/key'
assert open_cm_mock.write.call_count == 1