首页 > 解决方案 > 使用带有 Python 模拟的生成器来复制服务器响应

问题描述

我想使用一个列表(转换为生成器)作为我的 API 调用的模拟(使用unittest.mock)。我的功能是:

def monitor_order(order_id)
    order_info = client.get_order_status(order_id)
    order_status = order_info['status']

    while order_status != 'filled':
        print('order_status: ', order_status)
        time.sleep(5)
        order_info = client.get_order_status(order_id)
        order_status = order_info['status']

    return order_info

我的测试功能是:

@patch('my_package.client.get_order_status')
def test_monitor_order(mocked_get_order_status):
    order_states = [
        dict(status='open'),
        dict(status='open'),
        dict(status='filled'),
    ]

    # Make into a generator
    status_changes = (status for status in order_states)
    mocked_get_order_status.return_value = next(order_states)

    # Execute function to test
    monitor_order("dummy_order")

但是,我可以看到执行测试时状态始终为“打开”:

order_status:  open
order_status:  open
order_status:  open

我想我理解它为什么错了,但我怎样才能正确地实现它呢?

标签: pythonmockinggeneratorpatchpython-unittest.mock

解决方案


To achieve what you want, you can rewrite your test as follows:

@patch('my_package.client.get_order_status')
def test_monitor_order(mocked_get_order_status):
    order_states = [
        dict(status='open'),
        dict(status='open'),
        dict(status='filled'),
    ]

    mocked_get_order_status.side_effect = order_states

    # Execute function to test
    monitor_order("dummy_order")

推荐阅读