Open BobCashStory opened 3 years ago
okay i found a solution using https://github.com/miyakogi/syncer i replaced the mocker like that :
from .sanic_client import hightGetFunction, hightPostFunction
from syncer import sync
# import asyncio
def mock_job(requests_mock, test_sanic):
def post_json(request, context):
data = {}
res = sync(test_sanic.post(f"/test_post", json=data))
data_res = sync(res.json())
return data_res
def get_json(request, context):
data = {}
res = sync(test_sanic.get(f"/test_get", json=data))
data_res = sync(res.json())
return data_res
requests_mock.register_uri("GET", 'http://localhost:8000/test_get', json=get_json, status_code=200)
requests_mock.register_uri("POST", 'http://localhost:8000/test_post', json=post_json, status_code=200)
async def test_get(requests_mock, test_sanic):
mock_job(requests_mock, test_sanic)
data = hightGetFunction()
assert data == {"GET": True}
async def test_post(requests_mock, test_sanic):
mock_job(requests_mock, test_sanic)
data = hightPostFunction()
assert data == {"POST": True}
That's awesome.
No, I've never really used the async python features and this is the first time i've heard of sanic. Last I checked (a long time) the only requests async support was provided by some third party modules and there wasn't really a standard around that so it never progressed. Not that it matters here as it looks like the client is still using the standard sync, so you'd have to figure out that conversion somewhere.
Your example is interesting though, basically using requests-mock to build a bridge to an existing test api service.
If there's something specific there that would help i'd be happy to support it, but I don't know what it would be as requests is still fundamentally synchronous.
The only suggestion I'd have for a bridge like that is you can do it more generically (this is typed directly and won't compile, but i don't know what methods are available):
def callback(request, context):
# fetch is some made up function to convert request.method into a GET/POST etc request
res = sync(test_sanic.fetch(request.method, request.path, json=request.data))
context.status_code = res.status_code
context.headers.update(res.headers)
return res.data
def is_sanic(request):
return request.netloc == 'localhost' and request.port == 8080
requests_mock.register_uri(requests_mock.ANY, requests_mock.ANY, additional_matcher=is_sanic, data=callback)
or it might be easier to just go the custom matching route and do all request checking/response creation in one go. You lose some history tracking, but depends if you need that on a matcher.
def custom_matcher(request):
if request.netloc == 'localhost' and request.port == 8080:
# call sanic, create requests.Response (can use requests_mock.create_response for help)
return resp
requests_mock.add_matcher(custom_matcher)
i'm using request mock in my python package and i'm suck with a weird issue.
i need to use the mocker of other package instead of doing a http request but this one is async, so this doesn't work in request-mock, do you know any way to do it ?
Here are demo file:
__init__.py
conftest.py
sanic_server.py
sanic_client.py
test_sanic.py
TEST
with install:
pip install pytest sanic requests-mock pytest-sanic requests asyncio
Then i run :pytest
and i get :My question is: Does it's possible to have dynamic mock response with async in it ?