mirror of
https://github.com/graphql-python/graphene-django.git
synced 2024-11-28 12:33:43 +03:00
Extract query function from GraphQLTestCase making it possible to use in a pytest fixture (#1015)
This commit is contained in:
parent
97de26bf2e
commit
2308965658
|
@ -1,6 +1,9 @@
|
||||||
Testing API calls with django
|
Testing API calls with django
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
|
Using unittest
|
||||||
|
--------------
|
||||||
|
|
||||||
If you want to unittest your API calls derive your test case from the class `GraphQLTestCase`.
|
If you want to unittest your API calls derive your test case from the class `GraphQLTestCase`.
|
||||||
|
|
||||||
Your endpoint is set through the `GRAPHQL_URL` attribute on `GraphQLTestCase`. The default endpoint is `GRAPHQL_URL = "/graphql/"`.
|
Your endpoint is set through the `GRAPHQL_URL` attribute on `GraphQLTestCase`. The default endpoint is `GRAPHQL_URL = "/graphql/"`.
|
||||||
|
@ -12,12 +15,8 @@ Usage:
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from graphene_django.utils.testing import GraphQLTestCase
|
from graphene_django.utils.testing import GraphQLTestCase
|
||||||
from my_project.config.schema import schema
|
|
||||||
|
|
||||||
class MyFancyTestCase(GraphQLTestCase):
|
class MyFancyTestCase(GraphQLTestCase):
|
||||||
# Here you need to inject your test case's schema
|
|
||||||
GRAPHQL_SCHEMA = schema
|
|
||||||
|
|
||||||
def test_some_query(self):
|
def test_some_query(self):
|
||||||
response = self.query(
|
response = self.query(
|
||||||
'''
|
'''
|
||||||
|
@ -82,3 +81,38 @@ Usage:
|
||||||
|
|
||||||
# Add some more asserts if you like
|
# Add some more asserts if you like
|
||||||
...
|
...
|
||||||
|
|
||||||
|
Using pytest
|
||||||
|
------------
|
||||||
|
|
||||||
|
To use pytest define a simple fixture using the query helper below
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
# Create a fixture using the graphql_query helper and `client` fixture from `pytest-django`.
|
||||||
|
import pytest
|
||||||
|
from graphene_django.utils.testing import graphql_query
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def client_query(client)
|
||||||
|
def func(*args, **kwargs):
|
||||||
|
return graphql_query(*args, **kwargs, client=client)
|
||||||
|
|
||||||
|
return func
|
||||||
|
|
||||||
|
# Test you query using the client_query fixture
|
||||||
|
def test_some_query(client_query):
|
||||||
|
response = graphql_query(
|
||||||
|
'''
|
||||||
|
query {
|
||||||
|
myModel {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''',
|
||||||
|
op_name='myModel'
|
||||||
|
)
|
||||||
|
|
||||||
|
content = json.loads(response.content)
|
||||||
|
assert 'errors' not in content
|
|
@ -6,6 +6,7 @@ from mock import patch
|
||||||
|
|
||||||
from ..utils import camelize, get_model_fields, GraphQLTestCase
|
from ..utils import camelize, get_model_fields, GraphQLTestCase
|
||||||
from .models import Film, Reporter
|
from .models import Film, Reporter
|
||||||
|
from ..utils.testing import graphql_query
|
||||||
|
|
||||||
|
|
||||||
def test_get_model_fields_no_duplication():
|
def test_get_model_fields_no_duplication():
|
||||||
|
@ -58,3 +59,29 @@ def test_graphql_test_case_op_name(post_mock):
|
||||||
"operationName",
|
"operationName",
|
||||||
"QueryName",
|
"QueryName",
|
||||||
) in body.items(), "Field 'operationName' is not present in the final request."
|
) in body.items(), "Field 'operationName' is not present in the final request."
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
@patch("graphene_django.utils.testing.Client.post")
|
||||||
|
def test_graphql_query_case_op_name(post_mock):
|
||||||
|
graphql_query("query { }", op_name="QueryName")
|
||||||
|
body = json.loads(post_mock.call_args.args[1])
|
||||||
|
# `operationName` field from https://graphql.org/learn/serving-over-http/#post-request
|
||||||
|
assert (
|
||||||
|
"operationName",
|
||||||
|
"QueryName",
|
||||||
|
) in body.items(), "Field 'operationName' is not present in the final request."
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def client_query(client):
|
||||||
|
def func(*args, **kwargs):
|
||||||
|
return graphql_query(*args, client=client, **kwargs)
|
||||||
|
|
||||||
|
return func
|
||||||
|
|
||||||
|
|
||||||
|
def test_pytest_fixture_usage(client_query):
|
||||||
|
response = graphql_query("query { test }")
|
||||||
|
content = json.loads(response.content)
|
||||||
|
assert content == {"data": {"test": "Hello World"}}
|
||||||
|
|
|
@ -2,6 +2,63 @@ import json
|
||||||
|
|
||||||
from django.test import TestCase, Client
|
from django.test import TestCase, Client
|
||||||
|
|
||||||
|
DEFAULT_GRAPHQL_URL = "/graphql/"
|
||||||
|
|
||||||
|
|
||||||
|
def graphql_query(
|
||||||
|
query,
|
||||||
|
op_name=None,
|
||||||
|
input_data=None,
|
||||||
|
variables=None,
|
||||||
|
headers=None,
|
||||||
|
client=None,
|
||||||
|
graphql_url=None,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
query (string) - GraphQL query to run
|
||||||
|
op_name (string) - If the query is a mutation or named query, you must
|
||||||
|
supply the op_name. For annon queries ("{ ... }"),
|
||||||
|
should be None (default).
|
||||||
|
input_data (dict) - If provided, the $input variable in GraphQL will be set
|
||||||
|
to this value. If both ``input_data`` and ``variables``,
|
||||||
|
are provided, the ``input`` field in the ``variables``
|
||||||
|
dict will be overwritten with this value.
|
||||||
|
variables (dict) - If provided, the "variables" field in GraphQL will be
|
||||||
|
set to this value.
|
||||||
|
headers (dict) - If provided, the headers in POST request to GRAPHQL_URL
|
||||||
|
will be set to this value.
|
||||||
|
client (django.test.Client) - Test client. Defaults to django.test.Client.
|
||||||
|
graphql_url (string) - URL to graphql endpoint. Defaults to "/graphql".
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response object from client
|
||||||
|
"""
|
||||||
|
if client is None:
|
||||||
|
client = Client()
|
||||||
|
if not graphql_url:
|
||||||
|
graphql_url = DEFAULT_GRAPHQL_URL
|
||||||
|
|
||||||
|
body = {"query": query}
|
||||||
|
if op_name:
|
||||||
|
body["operationName"] = op_name
|
||||||
|
if variables:
|
||||||
|
body["variables"] = variables
|
||||||
|
if input_data:
|
||||||
|
if variables in body:
|
||||||
|
body["variables"]["input"] = input_data
|
||||||
|
else:
|
||||||
|
body["variables"] = {"input": input_data}
|
||||||
|
if headers:
|
||||||
|
resp = client.post(
|
||||||
|
graphql_url, json.dumps(body), content_type="application/json", **headers
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
resp = client.post(
|
||||||
|
graphql_url, json.dumps(body), content_type="application/json"
|
||||||
|
)
|
||||||
|
return resp
|
||||||
|
|
||||||
|
|
||||||
class GraphQLTestCase(TestCase):
|
class GraphQLTestCase(TestCase):
|
||||||
"""
|
"""
|
||||||
|
@ -9,19 +66,12 @@ class GraphQLTestCase(TestCase):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# URL to graphql endpoint
|
# URL to graphql endpoint
|
||||||
GRAPHQL_URL = "/graphql/"
|
GRAPHQL_URL = DEFAULT_GRAPHQL_URL
|
||||||
# Here you need to set your graphql schema for the tests
|
|
||||||
GRAPHQL_SCHEMA = None
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
super(GraphQLTestCase, cls).setUpClass()
|
super(GraphQLTestCase, cls).setUpClass()
|
||||||
|
|
||||||
if not cls.GRAPHQL_SCHEMA:
|
|
||||||
raise AttributeError(
|
|
||||||
"Variable GRAPHQL_SCHEMA not defined in GraphQLTestCase."
|
|
||||||
)
|
|
||||||
|
|
||||||
cls._client = Client()
|
cls._client = Client()
|
||||||
|
|
||||||
def query(self, query, op_name=None, input_data=None, variables=None, headers=None):
|
def query(self, query, op_name=None, input_data=None, variables=None, headers=None):
|
||||||
|
@ -43,28 +93,15 @@ class GraphQLTestCase(TestCase):
|
||||||
Returns:
|
Returns:
|
||||||
Response object from client
|
Response object from client
|
||||||
"""
|
"""
|
||||||
body = {"query": query}
|
return graphql_query(
|
||||||
if op_name:
|
query,
|
||||||
body["operationName"] = op_name
|
op_name=op_name,
|
||||||
if variables:
|
input_data=input_data,
|
||||||
body["variables"] = variables
|
variables=variables,
|
||||||
if input_data:
|
headers=headers,
|
||||||
if variables in body:
|
client=self._client,
|
||||||
body["variables"]["input"] = input_data
|
graphql_url=self.GRAPHQL_URL,
|
||||||
else:
|
|
||||||
body["variables"] = {"input": input_data}
|
|
||||||
if headers:
|
|
||||||
resp = self._client.post(
|
|
||||||
self.GRAPHQL_URL,
|
|
||||||
json.dumps(body),
|
|
||||||
content_type="application/json",
|
|
||||||
**headers
|
|
||||||
)
|
)
|
||||||
else:
|
|
||||||
resp = self._client.post(
|
|
||||||
self.GRAPHQL_URL, json.dumps(body), content_type="application/json"
|
|
||||||
)
|
|
||||||
return resp
|
|
||||||
|
|
||||||
def assertResponseNoErrors(self, resp):
|
def assertResponseNoErrors(self, resp):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue
Block a user