【问题标题】: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_openmock_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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-08
        • 2017-03-04
        • 2022-01-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多