这是我要测试的功能:

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而不调用它时才可以工作。

最佳答案

如果您可以将conn.recbuf更改为property,则可以使用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)


但是,对于您的实际问题,我认为对您的问题的评论似乎包含合理的方法。

09-16 00:01