python pytest mocker.patch.object的return_value使用的mock与我传递给它的mock不同

b5buobof  于 2023-02-11  发布在  Python
关注(0)|答案(1)|浏览(183)

我正在使用pytest为一个测试修补os.makedirs方法,在一个特定的测试中我想添加一个异常的副作用。
因此,我导入了在测试脚本中导入的os对象,对其进行了修补,然后在测试中设置了副作用:

from infrastructure.scripts.src.server_administrator import os

def mock_makedirs(self, mocker):
    mock = MagicMock()
    mocker.patch.object(os, "makedirs", return_value=mock)
    return mock

def test_if_directory_exist_exception_is_not_raised(self, administrator, mock_makedirs):
    mock_makedirs.side_effect = Exception("Directory already exists.")

    with pytest.raises(Exception) as exception:
        administrator.initialize_server()

    assert exception.value == "Directory already exists."

我遇到的问题是,当在测试脚本中调用mock时,副作用就不再存在了。在排除故障时,我停止了调试器中的测试,查看我创建的mock的ID值和补丁应该设置为返回值的mock的ID值,发现它们是不同的示例:

我对python中的一些测试工具还是比较陌生的,所以这可能是我在文档中遗漏了一些东西,但是这里返回的mock补丁不应该是我创建的mock吗?我打错补丁了吗?

更新

我甚至调整了导入风格,直接抓取makedirs来打补丁:

def mock_makedirs(self, mocker):
    mock = MagicMock()
    mocker.patch("infrastructure.scripts.src.server_administrator.makedirs", return_value=mock)
    return mock

而且我仍然遇到同样的"不同的模仿"问题。

igetnqfo

igetnqfo1#

:面部手掌:
我打错了补丁。我正在考虑删除整个问题/答案,但我想我还是把它留在这里,以防有人遇到同样的情况。
我这样定义补丁:

mocker.patch.object(os, "makedirs", return_value=mock)

如果我把结果修补为函数/方法,那么哪个是有效的结构?也就是说,这个修补程序所说的是"当你调用makedir时,返回这个。
我实际上想做的是返回一个方法的mock * in place *,在它的当前形式中,我看到两个不同的mock是有意义的,因为补丁逻辑当前是"用一个新的mock替换makedirs,然后当调用那个mock时,返回另一个mock(我创建的mock)"
我真正想要的只是:

mocker.patch.object(os, "makedirs", mock)

其中我的第三个参数(patch.object格式)是mock模块参数(相对于命名的return_value参数)。
回想起来,这是很明显的,当我想到它,这就是为什么我正在考虑删除的问题,但它是一个足够容易的绊倒,我打算离开它的生活现在。

相关问题