在python 3.5中模拟异步调用 - python

如何使用unittest.mock.patch模拟从一个本地协程到另一本地协程的异步调用?

我目前有一个很尴尬的解决方案:

class CoroutineMock(MagicMock):
    def __await__(self, *args, **kwargs):
        future = Future()
        future.set_result(self)
        result = yield from future
        return result

然后

class TestCoroutines(TestCase):
    @patch('some.path', new_callable=CoroutineMock)
    def test(self, mock):
        some_action()
        mock.assert_called_with(1,2,3)

这可行,但看起来很丑。有更多的pythonic方法可以做到这一点吗?

参考方案

子类MagicMock将传播自协程模拟生成的所有模拟的自定义类。例如,AsyncMock().__str__也将变成AsyncMock,这可能不是您想要的。

相反,您可能想定义一个工厂,该工厂使用自定义参数(例如Mock)创建MagicMock(或side_effect=coroutine(coro))。同样,将协程函数与协程分开也是一个好主意(如documentation中所述)。

这是我想出的:

from asyncio import coroutine

def CoroMock():
    coro = Mock(name="CoroutineResult")
    corofunc = Mock(name="CoroutineFunction", side_effect=coroutine(coro))
    corofunc.coro = coro
    return corofunc

不同对象的说明:

  • corofunc:协程函数模拟
  • corofunc.side_effect():为每个调用
  • 生成的协程

  • corofunc.coro:协程用于获取结果
  • 的模拟

  • corofunc.coro.return_value:协程
  • 返回的值

  • corofunc.coro.side_effect:可用于引发异常
  • 例:

    async def coro(a, b):
        return await sleep(1, result=a+b)
    
    def some_action(a, b):
        return get_event_loop().run_until_complete(coro(a, b))
    
    @patch('__main__.coro', new_callable=CoroMock)
    def test(corofunc):
        a, b, c = 1, 2, 3
        corofunc.coro.return_value = c
        result = some_action(a, b)
        corofunc.assert_called_with(a, b)
        assert result == c
    

    在python 3中使用单引号和双引号时出错 - python

    使用os.system()函数时,我在python中遇到了EOL错误。以下是代码行生成错误:os.system("cat subdomains.txt | cut -d'"' -f1 ") 基本上,我试图使用分号[“]修改输出字符串(双引号) 参考方案 如果需要在带"的字符串中编写",则可…

    在python-nvd3中的y轴上显示大量数字 - python

    在y轴上显示大量数字的一种方法是移动边距:Y axis label not displaying large numbers - Multi-Bar Chart。如何调整python-nvd3中的margin参数?您能代替写10 ^ 6这样的顶部指数并将y轴标记为2.5,3.0等吗,而不是写25,00,000,30,00,000等。 参考方案 如果我正确理解…

    在python ephem中,我无法获得某些星座的位置 - python

    import ephem date = '2018/9/20' sun = ephem.Sun() sun.compute(date) print 'Sun in', list(ephem.constellation(sun))[1] moon = ephem.Moon() moon.compute(date) pri…

    找不到满足要求pip的版本-在python 2.7中的代理后面安装pip - python

    我在实际要安装pip的地方使用Phyton 2.7,因此我从网站上获取了get-pip.py并尝试使用此命令安装pip:python get-pip.py 但是经过多次重试并显示此问题后它失败了Could not find a version that satisfies the requirement pip 我在不同的论坛上搜索,发现可能存在代理问题,因…

    在python flask应用程序中进行单元测试时如何避免装饰器 - python

    我是python和flask的新手。我想为编写的api创建单元测试。我们已经使用jwt进行身份验证。为了进行单元测试,我不想让流程进入@jwt_required装饰器。除此之外,我还为该方法链接了其他一些装饰器。class A(): @jwt_required() @mandatory_fields_check @unlock_and_lock() def …