如何编写Python测试验证内置字符串方法upper是否被调用
测试Python字符串upper方法调用的解决方案
报错原因解释
你之前的写法报错是因为直接写@patch("str.upper")时,mock会尝试查找名为str的第三方模块,而非Python内置的str类,同时Python默认不允许直接mock C实现的内置类型的实例方法,所以会触发找不到库'str'的报错。
正确实现方案
方案1:patch业务代码中引用的str类(适配你当前的代码写法)
因为你的业务函数里有str(str_to_upper)的强制类型转换逻辑,我们可以mock你业务代码中调用的str类,捕获它的返回实例的upper调用,代码示例如下:
# Python 3.3+ 直接使用标准库的unittest.mock,无需额外安装依赖 from unittest.mock import patch, MagicMock # 你的业务函数 def my_upper(str_to_upper: str) -> str: return str(str_to_upper).upper() def test_my_upper(): # 构造mock的str实例,自带mock的upper方法 mock_str_instance = MagicMock() # 构造mock的str类,调用时返回上面的mock实例 mock_str_cls = MagicMock(return_value=mock_str_instance) # 注意:patch的路径要替换为你的my_upper函数实际所在的模块 # 示例:如果my_upper定义在app.utils模块下,就写"app.utils.str" # 如果测试代码和业务函数在同一个文件,使用"__main__.str"即可 with patch("__main__.str", mock_str_cls): my_upper('test_input') # 验证str转换逻辑被正确调用 mock_str_cls.assert_called_once_with('test_input') # 验证upper方法被调用了至少一次 assert mock_str_instance.upper.call_count >= 1 # 也可以用更简洁的断言写法 # mock_str_instance.upper.assert_called_once()
方案2:传入mock参数(无强制str转换的场景适用)
如果你的业务函数没有强制转str的逻辑,直接对入参调用upper,可用更简单的写法:
from unittest.mock import MagicMock def my_upper(str_to_upper: str) -> str: # 没有str()强制转换的版本 return str_to_upper.upper() def test_my_upper_simple(): mock_param = MagicMock() my_upper(mock_param) mock_param.upper.assert_called_once()
注意事项
- patch路径必须正确:要patch的是业务代码实际导入、使用的str的所在模块路径,而非通用的str类路径,这是mock工具最常见的使用误区。
- 该类行为测试刚好匹配你的需求:如果后续其他开发修改了字符串处理逻辑,比如替换为手动实现大写转换、调用其他方法替代upper,测试会直接失败告警,不需要依赖返回值比对就能发现实现变更。
内容的提问来源于stack exchange,提问作者Mickers
相关产品推荐
相关产品推荐

