Python中如何添加无需传入mock参数的patch装饰器
Python中添加不注入mock入参的patch方法
默认情况下,使用@patch装饰测试类时,patch会自动将生成的mock对象作为额外入参,传入类下的所有测试方法,因此必须给每个测试方法增加对应的形参接收。要实现统一打补丁且不注入参数,可以用以下两种方案:
方案1:在setUp/tearDown中手动管理patch生命周期
这是最通用的实现方式,不会给测试方法注入任何额外参数,还可以灵活控制补丁的生效范围:
import datetime import unittest from unittest.mock import patch from django.utils import timezone class TestManyMethods(unittest.TestCase): def setUp(self): self.fixed_time = datetime.datetime(2022, 4, 22, tzinfo=timezone.utc) # 创建patcher并启动 self.time_patcher = patch( 'django.utils.timezone.now', return_value=self.fixed_time ) self.time_patcher.start() # 如果测试逻辑中不需要操作mock对象,也可以不绑定patcher到实例,直接调用start()即可 def tearDown(self): # 测试结束后停止patcher,避免补丁污染其他测试用例 self.time_patcher.stop() # 以下所有测试方法都不需要额外添加mock入参 def test_first_case(self): from django.utils.timezone import now self.assertEqual(now(), self.fixed_time) def test_second_case(self): # 自定义测试逻辑,timezone.now会直接返回固定时间 pass
方案2:通过new参数传入预构造的mock对象
当给patch传入new参数指定替换对象时,patch就不会再自动生成mock、也不会给测试方法注入额外参数。需要提前构造好mock对象并配置好返回规则:
import datetime import unittest from unittest.mock import Mock from django.utils import timezone # 提前构造mock对象,配置固定返回值 mock_now = Mock(return_value=datetime.datetime(2022, 4, 22, tzinfo=timezone.utc)) # 通过new参数传入预构造的mock,不要直接在patch中传return_value @patch('django.utils.timezone.now', new=mock_now) class TestManyMethods(unittest.TestCase): # 所有测试方法不需要额外接收mock参数 def test_first_case(self): from django.utils.timezone import now self.assertEqual(now().year, 2022) def test_second_case(self): # 自定义测试逻辑 pass
注意:如果直接在
@patch装饰器中传入return_value、side_effect参数而不指定new,patch会自动生成新的Mock实例,默认会将该实例作为参数注入所有被装饰的测试方法,这就是之前必须给每个方法加mock形参的原因。
内容的提问来源于stack exchange,提问作者spacether
相关产品推荐
相关产品推荐

