1

我正在尝试对 test_app 中的 requests.post 做猴子补丁,我正在使用来自 quart(rest-api) 的 test_client ,它是 async 。我从响应中得到的对象是好的,但是测试崩溃了

import my_app
import requests
import asyncio


import pytest

app = my_app.app
print(app)


class MockResponse:

    @staticmethod
    def json():
        data = {"status": "ok"}
        return data

    @staticmethod
    def status_code():
        return 200


# @asyncio.coroutine
@pytest.fixture(autouse=True)
def mock_response(monkeypatch):

    def mock_post(*args, **kwargs):
        return MockResponse()

    monkeypatch.setattr(requests, "post", mock_post, raising=True)


@pytest.mark.asyncio
async def test_app(mock_response):
    try:
        client = app.test_client()
        response = await client.post('/func')
        res_json = await response.get_json()
        print("response : " + str(response))
        print("response : " + str(response.status_code))
        print("response : " + str(res_json))
        assert response.status_code == 200
        assert res_json == {"status": "ok"}
    except Exception as e:
        print(e)


if __name__ == '__main__':
    pytest.main()

结果是:

pyfuncitem = <Function test_app>

    @pytest.mark.tryfirst
    def pytest_pyfunc_call(pyfuncitem):
        """
        Run asyncio marked test functions in an event loop instead of a normal
        function call.
        """
        for marker_name, fixture_name in _markers_2_fixtures.items():
            if marker_name in pyfuncitem.keywords \
                    and not getattr(pyfuncitem.obj, 'is_hypothesis_test', False):
                event_loop = pyfuncitem.funcargs[fixture_name]

                funcargs = pyfuncitem.funcargs
                testargs = {arg: funcargs[arg]
                            for arg in pyfuncitem._fixtureinfo.argnames}

                event_loop.run_until_complete(
                    asyncio.ensure_future(
>                       pyfuncitem.obj(**testargs), loop=event_loop))

/usr/local/lib/python3.7/dist-packages/pytest_asyncio/plugin.py:158: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

coro_or_future = None

    def ensure_future(coro_or_future, *, loop=None):
        """Wrap a coroutine or an awaitable in a future.

        If the argument is a Future, it is returned directly.
        """
        if coroutines.iscoroutine(coro_or_future):
            if loop is None:
                loop = events.get_event_loop()
            task = loop.create_task(coro_or_future)
            if task._source_traceback:
                del task._source_traceback[-1]
            return task
        elif futures.isfuture(coro_or_future):
            if loop is not None and loop is not futures._get_loop(coro_or_future):
                raise ValueError('loop argument must agree with Future')
            return coro_or_future
        elif inspect.isawaitable(coro_or_future):
            return ensure_future(_wrap_awaitable(coro_or_future), loop=loop)
        else:
>           raise TypeError('An asyncio.Future, a coroutine or an awaitable is '
                            'required')
E           TypeError: An asyncio.Future, a coroutine or an awaitable is required

/usr/lib/python3.7/asyncio/tasks.py:592: TypeError
----------------------------- Captured stdout call -----------------------------


ressssss <my_test.MockResponse object at 0x7f08c6466dd8>
response : Response(200)
response : 200
response : {'status': 'ok'}

即使来自模拟的值是好的值,它也会失败,这意味着函数将好的值返回给断言

4

0 回答 0