【问题标题】:mock a specific file with mock_open in Python在 Python 中使用 mock_open 模拟特定文件
【发布时间】:2023-02-26 16:10:26
【问题描述】:
我使用此代码 sn-p(来自:How do I mock a file open for a specific path in python?)
builtin_open = open
def my_mock_open(*args, **kwargs):
if args[0] == "myFile":
# mocked open for path "myFile"
return mock.mock_open()(*args, **kwargs)
# unpatched version for every other path
return builtin_open(*args, **kwargs)
def test_myfunc(mocker):
mocker.patch('builtins.open', my_mock_open)
myfunc()
这很好用,因为它只模拟对 myFile 的调用,而不模拟 myfunc() 从中读取的其他文件。
但我还想断言已尝试将正确的数据写入文件myFile。
我试图将模拟放在上下文“with as”语句中,但这没有用。
AttributeError: 'function' object has no attribute assert_called_with
【问题讨论】:
标签:
python
python-3.x
mocking
pytest
【解决方案1】:
您正在尝试在函数对象而不是模拟对象上使用 assert_called_with 方法。为了使用assert_called_with方法,您需要使用mock.Mock类或pytest-mock库提供的mocker.Mock方法创建模拟对象。下面是一个示例,说明如何修改测试以断言正确的数据已写入文件“myFile”:
import mock
builtin_open = open
def my_mock_open(*args, **kwargs):
if args[0] == "myFile":
# mocked open for path "myFile"
return mock.mock_open()(*args, **kwargs)
# unpatched version for every other path
return builtin_open(*args, **kwargs)
def test_myfunc(mocker):
with mocker.patch('builtins.open', my_mock_open) as mock_open:
myfunc()
mock_open.assert_called_with("myFile", "w")
mock_file_handle = mock_open()
mock_file_handle.write.assert_called_with("expected data")
在这个修改后的测试版本中,我们使用 mocker.patch 方法作为上下文管理器,用我们自定义的模拟实现 my_mock_open 修补 open 函数。我们还通过调用 mock.mock_open() 方法创建了一个 mock_open 对象,该对象将用于创建模拟文件句柄对象。然后我们调用myfunc(),最后对mock_open和mock_file_handle对象进行断言,以确保将正确的数据写入“myFile”文件。
【解决方案2】:
我现在更进一步了。
将装饰器更改为
@mock.patch("builtins.open", side_effect=my_mock_open)
然后在测试函数的参数中添加一个参数
def test_myfunc(open_mock, mocker):
然后我可以做例如
assert open_mock.call_count == 1