Атрибут насмешки меняется каждый раз, когда к нему обращаются - PullRequest
2 голосов
/ 29 марта 2019

Вот функция, которую я хочу проверить:

def send_something():
    conn = lib.conn.SSH1
    conn.open()
    conn.send('ls\n')
    if 'home' not in conn.recbuf:
        return lib.FAIL

    conn.send('whoami\n')
    if USER not in conn.recbuf:
        return lib.FAIL
    return lib.PASS

Каждый раз, когда я вызываю conn.send (), результат вызова сохраняется в conn.recbuf. Чтобы проверить это, мне нужно, чтобы conn.recbuf отличался при каждом вызове. (Я знаю, что мог бы просто изменить conn.recbuf на строку, содержащую как home, так и USER, но это не сработает для более сложных функций)

Вот что я придумал в своем тесте:

@mock.patch.object(demo_sequence.lib, 'conn')
def test_send_something(mock_conn):
    mock_conn.SSH1.recbuf = 'home'
    assert demo_sequence.lib.PASS == demo_sequence.send_something()
    mock_conn.SSH1.send.assert_any_call('ls\n')
    mock_conn.SSH1.send.assert_any_call('whoami\n')

Очевидно, что это не сработало, потому что conn.recbuf только home и не содержит USER.

Мне нужно что-то вроде conn.recbuf.side_effect = ['home', USER], но оно будет работать, когда просто ссылаешься на recbuf и не вызываешь его.

Ответы [ 2 ]

1 голос
/ 02 апреля 2019

Если вы можете изменить conn.recbuf на свойство , вы можете использовать PropertyMock для достижения желаемого эффекта.

from unittest import mock

class Dummy:

    def __init__(self, myattribute):
        self._myattribute = myattribute

    @property
    def myattribute(self):
        return self._myattribute

def test():
    with mock.patch('__main__.Dummy.myattribute', new_callable=mock.PropertyMock) as mocked_attribute:
        mocked_attribute.side_effect = [4,5,6]
        d = Dummy("foo")
        print(d.myattribute)
        print(d.myattribute)
        print(d.myattribute)

Однако для вашей актуальной проблемы я думаю, что комментарии к вашему вопросу, кажется, включают разумные подходы.

0 голосов
/ 31 марта 2019

То, что вы ищете, это side_effect: https://docs.python.org/3/library/unittest.mock.html

Допустим, mock это ваш фиктивный объект.Затем вы можете сделать это:

mock.side_effect = [a,b,c]

, затем каждый раз, когда вы вызываете mock, возвращается следующее значение из списка.

mock() # -> a
mock() # -> b
mock() # -> c
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...