You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python unittest中使用mock替换randint不生效的问题如何解决?

问题原因

你的代码存在三个核心问题导致mock不生效/运行报错:

  • 测试类的类属性NUMBER在测试类加载阶段就完成了Calculator实例初始化,此时测试方法的@mock.patch装饰器还未生效,Calculator.__init__中调用的randint是官方库的真实方法,self.number2已经被赋值为真实随机值,后续测试执行时再mock已经不会影响已经生成的属性值。
  • 不符合mock的「在哪里使用,就mock哪里」原则:你的代码通过from random import randint把randint导入到了当前模块的命名空间,直接mockrandom.randint不会修改当前模块已经导入的randint引用,mock无法作用到Calculator的逻辑中。
  • @mock.patch装饰的测试方法会自动把mock对象作为入参传入,你的代码没有定义对应的形参会直接触发运行报错。
修复方案

调整初始化时机和mock路径即可,修改后可正常运行的代码如下:

from random import randint
import unittest
from unittest import mock


class Calculator:
    def __init__(self, number):
        self.number = number
        self.number2 = randint(1, 5)

    def multi(self):
        return self.number * self.number2


class CalculatorTest(unittest.TestCase):
    # 用__name__动态获取当前模块名,mock当前模块命名空间下的randint
    @mock.patch(f'{__name__}.randint', return_value=4)
    def test_multi(self, mock_randint):
        # mock生效后再初始化Calculator,此时__init__调用的是mock后的randint
        test_calculator = Calculator(3)
        actual_result = test_calculator.multi()
        expected_result = 12
        self.assertEqual(actual_result, expected_result,
                         f'Actual result {actual_result}, expected {expected_result}')

if __name__ == '__main__':
    unittest.main()

如果后续你把Calculator类拆分到了单独的calculator.py模块,只需要把mock路径修改为@mock.patch('calculator.randint', return_value=4)即可。

内容的提问来源于stack exchange,提问作者Dzmitry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 09:45:04