【问题标题】:Mocking instance attributes模拟实例属性
【发布时间】:2020-03-03 21:28:33
【问题描述】:

请帮助我了解为什么以下内容不起作用。 特别是 - Python 的unittest.Mock 看不到测试类的实例属性。

在下面的示例中,bar 实例属性不可访问。 返回的错误是:

AttributeError: <class 'temp.Foo'> does not have the attribute 'bar'
import unittest
from unittest.mock import patch

class Foo:
    def __init__(self):
        super().__init__(self)
        self.bar = some_external_function_returning_list()

    def do_someting(self):
        calculate(self.bar)

class TestFoo(unittest.TestCase):

    @patch('temp.Foo.bar')
    def test_do_something(self, patched_bar):
        patched_bar.return_value = ['list_elem1', 'list_elem2']

【问题讨论】:

  • Foo.bar(类属性)和Foo().bar(实例属性)是两个不同的东西。没有要修补的现有类属性。
  • @chepner 我非常理解,这就是为什么我只询问实例属性。
  • 在不知道您到底想测试什么的情况下,我不建议您修补任何东西。无论您为测试创建 fFoo 的任何实例,您都可以简单地使用 f.bar = "mocked" 更改属性值。
  • @chepner 我已经对帖子进行了一些编辑。我明白我可以使用你的技术或模拟some_external_function_returning_list(),但我不明白为什么我不能按照我尝试的方式去做。非常相似的方法可用于类属性,例如在这里描述:stackoverflow.com/questions/22324628/…
  • property 不创建实例属性;它创建了一个属性,它是一种特殊的 class 属性,当它通过实例访问时提供回调。鉴于您对Foo 的定义,我怀疑您在调用Foo.__init__ 期间要修补的是some_external_function_returning_list

标签: python unit-testing mocking


【解决方案1】:

修补用于修改名称或属性查找。在这种情况下,没有temp.Foobar 属性。

如果意图是修补 instance 变量,您要么需要一个现有的实例来修改

def test(self):
    f = Foo()
    with patch.object(f, 'bar', 3):
        self.assertEqual(f.bar, 3)

或者您可能希望首先修补初始化实例属性的函数调用。

def test(self):
    with patch('some_external_function_returning_list', return_value=3):
        f = Foo()
    self.assertEqual(f.bar, 3)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-27
    • 2021-11-16
    相关资源
    最近更新 更多