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

如何在Pytest中无需getter方法Mock类的实例变量

当然有更简洁的实现方式!你完全可以直接Mock Print 实例的 self.foo 属性,同时删掉冗余的 get_foo 方法。下面一步步给你演示优化方案:

第一步:优化主代码

先把main.py里的get_foo方法删掉,让Process.run直接访问实例属性foo,同时记得补充print_hoge方法(原代码里run调用了这个方法,但Print类没定义,会导致测试报错):

class Process:
    def run(self):
        p = Print()
        if p.foo is True:  # 直接访问实例属性,无需getter
            p.print_hoge()

class Print:
    def __init__(self):
        self.foo = True
    def print_foo(self):
        print(self.foo)
    def print_hoge(self):  # 补充被调用的方法
        print("hoge")

第二步:编写优化后的测试代码

这里提供几种常用的Mock实例属性的方式,你可以根据场景选择:

方式1:用PropertyMock直接Mock类属性(最简洁)

这种方式可以直接让Print实例的foo属性返回指定值,无需修改初始化逻辑:

import main
import pytest

def test_run(mocker):
    # Mock print_hoge方法,用来验证是否被调用
    mock_print_hoge = mocker.patch("main.Print.print_hoge")
    
    # 让Print实例的foo属性返回False
    mocker.patch("main.Print.foo", new_callable=mocker.PropertyMock, return_value=False)
    
    p = main.Process()
    p.run()
    
    # 因为foo是False,print_hoge不应该被调用
    mock_print_hoge.assert_not_called()

方式2:修改__init__方法设置属性

如果需要更灵活的控制实例初始化逻辑,可以patchPrint的__init__方法,在初始化时修改foo:

def test_run_with_patched_init(mocker):
    mock_print_hoge = mocker.patch("main.Print.print_hoge")
    
    # 保留原初始化逻辑,仅修改foo的值
    original_init = main.Print.__init__
    def patched_init(self):
        original_init(self)
        self.foo = False
    
    mocker.patch.object(main.Print, "__init__", side_effect=patched_init)
    
    p = main.Process()
    p.run()
    
    mock_print_hoge.assert_not_called()

方式3:捕获实例并修改属性

如果你需要在实例创建后动态修改属性,可以自定义实例创建逻辑,修改后再返回:

def test_run_with_custom_instance(mocker):
    mock_print_hoge = mocker.patch("main.Print.print_hoge")
    
    # 自定义Print实例创建逻辑:创建后修改foo
    def create_print_instance():
        instance = main.Print()
        instance.foo = False
        return instance
    
    mocker.patch("main.Print", side_effect=create_print_instance)
    
    p = main.Process()
    p.run()
    
    mock_print_hoge.assert_not_called()

关键说明

  • 所有方案都不需要保留get_foo方法,直接操作实例属性foo,让代码更简洁符合Python风格。
  • 测试时要确保Print类有print_hoge方法,否则运行run时会抛出AttributeError。

内容的提问来源于stack exchange,提问作者Ryohei De Iwata

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 11:57:34