如何在Python中Mock全局对象的方法?附代码场景
如何测试依赖全局模块对象的工具函数
咱先理清楚你的场景:你有个twitter.py文件,里面放着全局的user和tweet对象;然后twitter_utils.py导入了twitter模块,写了两个依赖这些全局对象的私有方法;现在你要写test_twitter_utils.py来测试这俩方法对吧?
下面给你一步步说怎么搞:
1. 核心问题在哪?
你的工具函数直接依赖twitter模块里的全局对象,要是直接跑测试,肯定得依赖真实的twitter实现——这显然不是单元测试该干的事,所以咱们得模拟这些全局对象的方法,把依赖隔离开。
2. 用Python标准库unittest.mock搞定(最稳妥的方案)
我给你写个完整的test_twitter_utils.py示例,用unittest框架配合mock来模拟:
import unittest from unittest.mock import patch, MagicMock import twitter_utils class TestTwitterUtils(unittest.TestCase): @patch('twitter_utils.twitter.user') def test_get_user_date_of_birth(self, mock_user): # 先模拟user.get_date_of_birth的返回值 mock_user.get_date_of_birth.return_value = '1990-01-01' # 调用咱们要测的函数 result = twitter_utils.__get_user_date_of_birth(user_id=123) # 验证结果对不对 self.assertEqual(result, '1990-01-01') # 再确认方法是不是被正确调用了(参数也得对上) mock_user.get_date_of_birth.assert_called_once_with(userId=123) @patch('twitter_utils.twitter.tweet') def test_get_tweet_likes_count(self, mock_tweet): # 模拟tweet.getLikesCount的返回值 mock_tweet.getLikesCount.return_value = 500 # 调用测试函数 result = twitter_utils.__get_tweet_likes_count(user_id=123, tweet_id=456) # 验证结果和调用情况 self.assertEqual(result, 500) mock_tweet.getLikesCount.assert_called_once_with(123, 456) if __name__ == '__main__': unittest.main()
3. 几个关键点得注意
@patch的路径别写错:要patch的是twitter_utils里导入的那个twitter.user,不是原始的twitter模块——毕竟你的工具函数用的是自己导入的引用,得替换对地方才行。MagicMock帮你省事儿:patch会自动生成MagicMock对象来代替被模拟的对象,你可以用return_value设返回值,用assert_called_once_with检查方法有没有被正确调用、参数对不对。- 私有函数照样测:虽然你的方法是
__开头的私有函数,但Python的私有命名只是个约定,测试里直接调用就行,不用纠结。
4. 要是你用pytest,代码可以更简洁
如果你习惯用pytest框架,测试代码能写得更清爽:
from unittest.mock import patch, MagicMock import twitter_utils def test_get_user_date_of_birth(): with patch('twitter_utils.twitter.user') as mock_user: mock_user.get_date_of_birth.return_value = '1990-01-01' result = twitter_utils.__get_user_date_of_birth(user_id=123) assert result == '1990-01-01' mock_user.get_date_of_birth.assert_called_once_with(userId=123) def test_get_tweet_likes_count(): with patch('twitter_utils.twitter.tweet') as mock_tweet: mock_tweet.getLikesCount.return_value = 500 result = twitter_utils.__get_tweet_likes_count(user_id=123, tweet_id=456) assert result == 500 mock_tweet.getLikesCount.assert_called_once_with(123, 456)
内容的提问来源于stack exchange,提问作者nightfury
相关产品推荐
相关产品推荐

