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

如何Mock类的属性(另一个类的实例)以调用其方法?

问题与解决方案

问题描述

在测试Bar类的bar方法时,尝试Mock其foo属性(类型为Foo类实例),但用字符串"MockedFoo"作为Foo的Mock返回值,导致调用test_obj.bar()时抛出AttributeError: 'str' object has no attribute 'search'。需要修改Mock方式,让Bar的foo对象能调用Foo的search方法,且该方法返回指定列表。

原代码:

import unittest
from mock import patch


class Foo(object):
    def __init__(self):
        self.foo = 'foo'
    
    def search(self):
        # do something

class Bar(object):
    def __init__(self):
        self.id = "123"
        self.name = "abc"
        self.foo = Foo()

    def bar(self):
        return self.foo.search()
    

def test_bar():
# initialization of Bar object
    with mock.patch('lib.lib_foo.Foo', return_value="MockedFoo"):
        test_obj = Bar()
    test_obj.bar()

解决方案

你需要Mock一个包含search方法的对象,而不是字符串。有两种常用方法:

方法1:Mock Foo类,让其返回带search方法的Mock实例

修改patch的return_value为Mock对象,并给这个Mock的search方法设置返回值:

import unittest
from mock import patch, Mock  # 导入Mock

class Foo(object):
    def __init__(self):
        self.foo = 'foo'
    
    def search(self):
        # do something

class Bar(object):
    def __init__(self):
        self.id = "123"
        self.name = "abc"
        self.foo = Foo()

    def bar(self):
        return self.foo.search()
    

def test_bar():
    # 创建Mock对象,给search方法设置返回列表
    mocked_foo = Mock()
    mocked_foo.search.return_value = ["item1", "item2"]
    
    # patch Foo类,让它返回这个Mock对象
    with patch('lib.lib_foo.Foo', return_value=mocked_foo):
        test_obj = Bar()
        result = test_obj.bar()
        # 验证结果是否符合预期
        assert result == ["item1", "item2"]

方法2:直接Mock Bar实例的foo属性(更精准)

如果不需要Mock整个Foo类,而是只针对当前test_obj的foo属性,可以直接patch实例的属性:

import unittest
from mock import patch, Mock

class Foo(object):
    def __init__(self):
        self.foo = 'foo'
    
    def search(self):
        # do something

class Bar(object):
    def __init__(self):
        self.id = "123"
        self.name = "abc"
        self.foo = Foo()

    def bar(self):
        return self.foo.search()
    

def test_bar():
    test_obj = Bar()
    # 创建带search方法的Mock对象
    mocked_foo = Mock()
    mocked_foo.search.return_value = ["test_result"]
    
    # 直接替换test_obj的foo属性
    with patch.object(test_obj, 'foo', mocked_foo):
        result = test_obj.bar()
        assert result == ["test_result"]

两种方法都能解决问题,方法2更聚焦于当前实例的属性,避免影响其他地方的Foo类使用。

内容的提问来源于stack exchange,提问作者Muhammad Shaheer Munir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 21:05:53