如何使用 mox 模拟类属性?

发布于 2024-08-26 20:35:47 字数 580 浏览 2 评论 0原文

我有一堂课:

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

使用 moxpy .test,如何模拟 myproperty

我已经尝试过:

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

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

都失败了 AttributeError: can't set attribute

I have a class:

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

Using mox and py.test, how do I mock out myproperty?

I've tried:

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

and

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

but both fail with AttributeError: can't set attribute.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

紫瑟鸿黎 2024-09-02 20:35:47

当删除类属性时,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__ 和 < code>__set__ 方法,而不是实际“模拟”属性本身。

因此,为了获得您想要的结果,您只需更深入地模拟实例类上的属性即可。

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

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

When stubbing out class attributes mox uses setattr. Thus

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

is equivalent to

# 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)

Note that because myproperty is a property getattr and setattr will be invoking the property's __get__ and __set__ methods, rather than actually "mocking out" the property itself.

Thus to get your desired outcome you just go one step deeper and mock out the property on the instance's class.

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

Note that this might cause issues if you wish to concurrently mock multiple instances of MyClass with different myproperty values.

夏见 2024-09-02 20:35:47

您读过属性吗?它是只读的,是一个“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 )

Have you read about property? It's read-only, a "getter".

If you want a setter, you have two choices of how to create that.

Once you have both getter and setter, you can try again to mock out both of them.

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

Or

class MyClass(object): # Upper Case Names for Classes.
    def getProperty(self):
        return 'hello'
    def setProperty(self,value):
        self.someValue= value
    myproperty= property( getProperty, setProperty )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文