【问题标题】:How do I mock a class property with mox?如何使用 mox 模拟类属性?
【发布时间】:2011-01-31 12:45:18
【问题描述】:

我有一堂课:

class MyClass(object):
    @property
    def myproperty(self):
        return 'hello'

使用mox 和py.test,我如何模拟出myproperty?

我试过了:

mock.StubOutWithMock(myclass, 'myproperty')
myclass.myproperty = 'goodbye'

和

mock.StubOutWithMock(myclass, 'myproperty')
myclass.myproperty.AndReturns('goodbye')

但两者都以AttributeError: can't set attribute 失败。

【问题讨论】:

  • 请使用大写的类名。

标签: python mocking properties mox


【解决方案1】:

当存根类属性mox 使用setattr。因此

mock.StubOutWithMock(myinstance, 'myproperty')
myinstance.myproperty = 'goodbye'

等价于

# Save old attribute so it can be replaced during teardown
saved = getattr(myinstance, 'myproperty')
# Replace the existing attribute with a mock
mocked = MockAnything()
setattr(myinstance, 'myproperty', mocked)

请注意,因为myproperty 是属性,所以getattr 和setattr 将调用属性的__get__ 和__set__ 方法,而不是实际“模拟”属性本身。

因此,要获得您想要的结果,您只需更深入一步并模拟实例类上的属性。

mock.StubOutWithMock(myinstance.__class__, 'myproperty')
myinstance.myproperty = 'goodbye'

请注意,如果您希望同时模拟具有不同 myproperty 值的多个 MyClass 实例,这可能会导致问题。

【讨论】:

    【解决方案2】:

    你读过property吗?它是只读的,是一个“getter”。

    如果你想要一个 setter,你有两种选择如何创建它。

    当你同时拥有 getter 和 setter 后,你可以再次尝试模拟它们。

    class MyClass(object): # Upper Case Names for Classes.
        @property
        def myproperty(self):
            return 'hello'
        @myproperty.setter
        def myproperty(self,value):
            self.someValue= value
    

    或者

    class MyClass(object): # Upper Case Names for Classes.
        def getProperty(self):
            return 'hello'
        def setProperty(self,value):
            self.someValue= value
        myproperty= property( getProperty, setProperty )
    

    【讨论】:

    • 是的,我希望不修改原始类而侥幸逃脱,但可能是不可能的。
    • 你不能模拟不存在的东西。原始类无法设置属性。您无法模拟该功能,因为它不存在。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多