Python имитирующий асинхронный метод - PullRequest
0 голосов
/ 05 мая 2020

Я не могу обернуть голову вокруг этого:

import asyncio
from unittest import create_autospec

import pytest


def create_future(result: Any, loop: asyncio.AbstractEventLoop) -> Any:
    f = asyncio.Future(loop=loop)
    f.set_result(result)
    return f


class Foo:
    async def process(self, arg1: str, arg2: str) -> None:
        await self.some_processing()

    async def some_processing(self) -> None:
        ...

class Bar:
    def __init__(self, foo: Foo):
        self._foo = foo

    async def do_something(self, arg1: str, arg2: str) -> None:
        await self._foo.process(arg1, arg2)


@pytest.mark.asyncio
async def test_do_something(event_loop: asyncio.AbstractEventLoop):
    foo_mock = create_autospec(Foo, spec_set=True)
    foo_mock.some_processing.return_value = create_future("3", event_loop)
    bar = Bar(foo)
    await bar.do_something("1", "2")
    foo_mock.process.assert_called_once_with("1", "2")

Что, конечно, не работает с

TypeError: object MagicMock can't be used in 'await' expression

Мой вопрос: как я могу добиться следующего поведения - я делаю некоторые маги c и foo.process издеваются с желаемыми аргументами, и я не получаю TypeError на await foo.process(arg1, arg2)?

Я использую python 3.7, я знаю, что python 3.8 имеет AsyncMock , но python 3.8 я бы не смог использовать.

...