MagicMock assert_called未识别调用:测试代码问题排查
问题:MagicMock测试断言失败的原因及修复
问题描述
我在example.py中定义了如下函数:
def my_func(file): conn = get_connection() conn.upload_file(file) conn.execute_file(file)
我使用MagicMock编写测试代码test_example.py如下:
@mock.patch("example.get_connection") def test_my_func(mock_conn): mock_conn = MagicMock() mock_conn.upload_file = MagicMock(return_value=True) result= my_func("file.zip") mock_conn.upload_file.assert_called()
测试失败,报错:
if self.call_count == 0: msg = ("Expected '%s' to have been called." % (self._mock_name or 'mock')) > raise AssertionError(msg) E AssertionError: Expected 'upload_file' to have been called.
调试发现,在example.py中MagicMock的called属性在调用后为True,但回到test_example.py中该属性为False,测试失败。请问我哪里出错了?
解决方案
错误原因
你在测试函数里重新给mock_conn赋值了新的MagicMock实例,直接覆盖了@mock.patch装饰器注入的mock对象。my_func里调用get_connection()返回的是装饰器注入的原mock,而你断言的是自己新建的另一个无关mock,二者不是同一个对象,所以断言必然失败。
修复后的测试代码
不需要重新创建MagicMock,直接使用装饰器注入的mock_conn,配置它的返回值即可(get_connection()返回的conn对象对应mock_conn.return_value,需要给这个返回值配置方法):
@mock.patch("example.get_connection") def test_my_func(mock_conn): # 配置get_connection()返回的conn对象的upload_file方法 mock_conn.return_value.upload_file.return_value = True my_func("file.zip") # 断言upload_file被正确调用 mock_conn.return_value.upload_file.assert_called_once_with("file.zip") # 可选:同时断言execute_file也被调用 mock_conn.return_value.execute_file.assert_called_once_with("file.zip")
如果觉得链式调用不够清晰,也可以拆分写法:
@mock.patch("example.get_connection") def test_my_func(mock_conn): mock_conn_instance = MagicMock() mock_conn.return_value = mock_conn_instance mock_conn_instance.upload_file.return_value = True my_func("file.zip") mock_conn_instance.upload_file.assert_called_once_with("file.zip")
这样断言的mock对象和my_func里实际使用的是同一个,就能通过测试了。
内容的提问来源于stack exchange,提问作者Ni3dzwi3dz
相关产品推荐
相关产品推荐

