Testing#
pytest#
pjrpc implements pytest plugin that simplifies JSON-RPC requests mocking.
To install the plugin add the following line to your pytest configuration:
pytest_plugins = ("pjrpc.client.integrations.pytest_aiohttp", )
or
pytest_plugins = ("pjrpc.client.integrations.pytest_requests", )
or export the environment variable PYTEST_PLUGINS=pjrpc.client.integrations.pytest_aiohttp.
For more information see.
Look at the following test example:
from unittest import mock
import pytest
import pjrpc
from pjrpc.client.backend import aiohttp as aiohttp_client
from pjrpc.client.integrations.pytest_aiohttp import PjRpcAiohttpMocker
async def test_using_fixture(pjrpc_aiohttp_mocker):
client = aiohttp_client.Client('http://localhost/api/v1')
pjrpc_aiohttp_mocker.add('http://localhost/api/v1', 'sum', result=2)
result = await client.proxy.sum(1, 1)
assert result == 2
pjrpc_aiohttp_mocker.replace(
'http://localhost/api/v1', 'sum', error=pjrpc.exc.JsonRpcError(code=1, message='error', data='oops'),
)
with pytest.raises(pjrpc.exc.JsonRpcError) as exc_info:
await client.proxy.sum(a=1, b=1)
assert exc_info.type is pjrpc.exc.JsonRpcError
assert exc_info.value.code == 1
assert exc_info.value.message == 'error'
assert exc_info.value.data == 'oops'
localhost_calls = pjrpc_aiohttp_mocker.calls['http://localhost/api/v1']
assert localhost_calls[('2.0', 'sum')].call_count == 2
assert localhost_calls[('2.0', 'sum')].mock_calls == [mock.call(1, 1), mock.call(a=1, b=1)]
async def test_using_resource_manager():
client = aiohttp_client.Client('http://localhost/api/v1')
with PjRpcAiohttpMocker() as mocker:
mocker.add('http://localhost/api/v1', 'div', result=2)
result = await client.proxy.div(4, 2)
assert result == 2
localhost_calls = mocker.calls['http://localhost/api/v1']
assert localhost_calls[('2.0', 'div')].mock_calls == [mock.call(4, 2)]
For testing server-side code you should use framework-dependant utils and fixtures. Since pjrpc can be easily
extended you are free from writing JSON-RPC protocol related code.
aiohttp#
Testing aiohttp server code is very straightforward:
import pytest
from aiohttp import web
import pjrpc.server
from pjrpc.client.backend import aiohttp as async_client
from pjrpc.server.integration import aiohttp as integration
methods = pjrpc.server.MethodRegistry()
@methods.add()
async def div(a: int, b: int) -> float:
return a / b
@pytest.fixture
def http_app():
return web.Application()
@pytest.fixture
def jsonrpc_app(http_app):
jsonrpc_app = integration.Application('/api/v1', http_app=http_app)
jsonrpc_app.add_methods(methods)
return jsonrpc_app
async def test_pjrpc_server(aiohttp_client, http_app, jsonrpc_app):
jsonrpc_cli = async_client.Client('/api/v1', session=await aiohttp_client(http_app))
result = await jsonrpc_cli.proxy.div(4, 2)
assert result == 2
result = await jsonrpc_cli.proxy.div(6, 2)
assert result == 3
flask#
For flask it stays the same:
import flask.testing
import pytest
import werkzeug.test
import pjrpc.server
from pjrpc.client.backend import requests as client
from pjrpc.client.integrations.pytest_requests import PjRpcRequestsMocker
from pjrpc.server.integration import flask as integration
methods = pjrpc.server.MethodRegistry()
@methods.add()
def div(a: int, b: int) -> float:
return a / b
@pytest.fixture()
def http_app():
return flask.Flask(__name__)
@pytest.fixture
def jsonrpc_app(http_app):
json_rpc = integration.JsonRPC('/api/v1', http_app=http_app)
json_rpc.add_methods(methods)
return jsonrpc_app
class Response(werkzeug.test.Response):
def raise_for_status(self):
if self.status_code >= 400:
raise Exception('client response error')
@property
def text(self):
return self.data.decode()
@pytest.fixture()
def app_client(http_app):
return flask.testing.FlaskClient(http_app, Response)
def test_pjrpc_server(http_app, jsonrpc_app, app_client):
with PjRpcRequestsMocker(passthrough=True) as mocker:
jsonrpc_cli = client.Client('/api/v1', session=app_client)
mocker.add('http://127.0.0.2:8000/api/v1', 'div', result=2)
result = jsonrpc_cli.proxy.div(4, 2)
assert result == 2
result = jsonrpc_cli.proxy.div(6, 2)
assert result == 3