Ожидание свойства getter / setter в python с двойниками - PullRequest
0 голосов
/ 23 января 2019

Я использую удваивает вместе с pytest для модульного тестирования некоторого кода Python 2.7.

Допустим, у меня есть такой класс, как:

class Foo(object):
    def bar(self, value):
        pass

И у меня есть некоторый код, в который вставляется экземпляр Foo, и который вызывает method:

def do_bar(foo):
    foo.bar(22)

Я знаю, как создать ожидание

def test_doing_bar_sets_bar_to_22():
    foo = Foo()
    expect(foo).bar(22)
    do_bar(foo)

Но мне интересно, как создать ожидание для установщика свойства, определенного с помощью декоратора @property:

class Foo(object):
    def bar(self):
        pass

    @property
    def bee(self):
        pass

    @bee.setter
    def bee(self, value):
        pass

def do_bee(foo):
    foo.bee = 22

Чтобы сделать эту работу:

def test_doing_bee_sets_bee_to_22():
    foo = Foo()
    # Something like expect(foo.bee).setter(22)
    # I tried: expect(foo.__class__.bee).setter(foo, 22)
    do_bee(foo)

Я знаю, что мог бы просто создать класс со свойством bee, которое захватывает значение и передает этот экземпляр методу do_bee, но если возможно разрешить его с помощью подхода expect, я предпочитаю его за симметрию с остальным кодом и выразительность.

Можно ли сделать это с double ?

ОБНОВЛЕНИЕ 2019-01-24 Я провел некоторое исследование в исходном коде парных символов:

https://github.com/uber/doubles/blob/master/doubles/proxy_property.py

https://github.com/uber/doubles/blob/master/doubles/proxy_method.py

Я считаю, что реализация ProxyProperty не позволит создавать допуски / ожидания, когда свойство имеет установщик. В частности, я считаю, что __set__ должен быть реализован, но я не совсем понимаю , как должны работать допуски / ожидания в отношении свойств (с точки зрения дизайна).

Я мог бы заставить его работать, изменив реализацию ProxyProperty на:

class ProxyProperty(object):
    def __init__(self, name, original):
        self._name = name
        self._original = original

    def __get__(self, obj, objtype=None):
        return obj.__dict__.get(self._name, self._original.__get__(obj, objtype))

    def __set__(self, obj, value):
        obj.__dict__[self._name] = value

(Также в proxy_method.ProxyMethod._hijack_target я удаляю self._target.obj.__dict__[double_name(self._method_name)] = self, так как он больше не имеет смысла для меня после моих изменений).

С этими изменениями я могу написать:

def test_doing_bee_sets_bee_to_22():
    foo = Foo()
    allow(foo).bee
    do_bee(foo)
    assert foo.bee == 22

Однако я бы предпочел иметь такой механизм, как with_args (), потому что он позволил бы создать несколько ожиданий, если, например, doo_bee установит foo.bee несколько раз.

ОБНОВЛЕНИЕ 2019-02-23 Я открыл проблему на их странице Github, и они недавно пометили ее как ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...