使PropertyMock包装现有属性Python

2024-04-25 08:51:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我想测试在调用Python方法时,实例变量是否被“设置”为特定值(即多次)

PropertyMock替换实例变量允许我查看mock_calls并验证属性设置的值。但是,PropertyMock的行为与普通变量不同。当您在其上设置一个值并尝试读取它时,您将获得另一个模拟。有没有办法接收回该值

下面是一个人为的例子:

import time
from unittest.mock import PropertyMock, call


class Machine:

    def __init__(self):
        self.mode = "idle"

    def start(self):

        # Update mode
        self.mode = "running"

        # Do some work, e.g. drive a motor for 0.5 sec
        time.sleep(0.5)

        # Restore mode
        if self.mode == "running":         # Should always be True, but isn't when using PropertyMock
            self.mode = "idle"


class Test_Machine:

    def test(self):

        # Create a machine
        real_machine = Machine()

        # Mock the 'mode' property
        mocked_property = PropertyMock()
        type(real_machine).mode = mocked_property

        # Call the method to test
        real_machine.start()

        print(mocked_property.mock_calls)                         # [call('running'), call(), call().__eq__('running')]
        assert call("running") == mocked_property.mock_calls[0]   # Success
        assert call("idle") == mocked_property.mock_calls[-1]     # Fails here



Tags: 实例selfmodedefpropertymachinecallmock
1条回答
网友
1楼 · 发布于 2024-04-25 08:51:36

我相信有更好的方法可以做到这一点,但是如果您只是对属性setter的调用感兴趣,并且希望getter的行为与原始属性相同,那么您可以重写PropertyMock使其行为类似:

class MyPropertyMock(PropertyMock):
    def __init__(self, value=None):
        super().__init__()
        self.value = value

    def __get__(self, obj, obj_type):
        return self.value  # the mock will not register these calls

    def __set__(self, obj, val):
        self.value = val
        super().__set__(obj, val)  # ensure the mock behavior in the setter


class Test_Machine:
    def test(self):
        real_machine = Machine()
        mocked_property = MyPropertyMock(real_machine.value)
        Machine.mode = mocked_property

        real_machine.start()

        print(mocked_property.mock_calls)  # [call('running'), call('idle')]
        ...

相关问题 更多 >

    热门问题