如何直接模拟函数(Python)

时间:2019-05-06 11:24:05

标签: python mocking python-unittest

我们创建模拟对象并指定在其上调用的方法的行为:

from unittest.mock import patch, Mock

execute = Mock()
execute.fetchone = Mock(return_value={'state': json.dumps({})})
with patch('modules.data_chat.chatbot.execute', new=lambda x, y, z: execute):
        auto_reply(None, "test_user_id", "Hello?", 1)

assert execute.fetchone.called
assert execute.called

正在测试(自动回复)的代码:

from tools.db_tools import execute
[...]
cur = execute(conn, sql, (bot_id, channel_id))
state = cur.fetchone()

返回测试代码execute.fetchone.called == True。但是,execute.called == False

为什么execute.called == False是怎么解决的? new=lambda x, y, z: execute是正确的吗?

2 个答案:

答案 0 :(得分:3)

因为您没有打电话。您调用了一个lambda,它返回了它。

我不确定您为什么要这样做。您应该使用模拟。

fetchone = Mock(return_value={'state': json.dumps({})})
execute = Mock(return_value=fetchone)
with patch('modules.data_chat.chatbot.execute', new=execute):
    ...

答案 1 :(得分:0)

@Daniel Roseman使我步入正轨。不过,他的回答中缺少一个环节。 execute不应直接返回fetchone,而应该是游标模拟;可以嘲弄fetchone。我为模拟添加了名称以进行调试:

cursorMock = Mock(name="cursorMock")
cursorMock.fetchone = Mock(name="fetchoneMock", return_value={'state': json.dumps({})})

execute = Mock(name="executeMock", return_value=cursorMock)
with patch('modules.data_chat.chatbot.execute', new=execute):
    ...

assert cursorMock.fetchone.called
assert execute.called