mirror of
https://github.com/graphql-python/graphene-django.git
synced 2024-11-24 18:44:08 +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
|
||||
=============================
|
||||
|
||||
Using unittest
|
||||
--------------
|
||||
|
||||
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/"`.
|
||||
|
@ -12,12 +15,8 @@ Usage:
|
|||
import json
|
||||
|
||||
from graphene_django.utils.testing import GraphQLTestCase
|
||||
from my_project.config.schema import schema
|
||||
|
||||
class MyFancyTestCase(GraphQLTestCase):
|
||||
# Here you need to inject your test case's schema
|
||||
GRAPHQL_SCHEMA = schema
|
||||
|
||||
def test_some_query(self):
|
||||
response = self.query(
|
||||
'''
|
||||
|
@ -82,3 +81,38 @@ Usage:
|
|||
|
||||
# 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 .models import Film, Reporter
|
||||
from ..utils.testing import graphql_query
|
||||
|
||||
|
||||
def test_get_model_fields_no_duplication():
|
||||
|
@ -58,3 +59,29 @@ def test_graphql_test_case_op_name(post_mock):
|
|||
"operationName",
|
||||
"QueryName",
|
||||
) 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
|
||||
|
||||
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):
|
||||
"""
|
||||
|
@ -9,19 +66,12 @@ class GraphQLTestCase(TestCase):
|
|||
"""
|
||||
|
||||
# URL to graphql endpoint
|
||||
GRAPHQL_URL = "/graphql/"
|
||||
# Here you need to set your graphql schema for the tests
|
||||
GRAPHQL_SCHEMA = None
|
||||
GRAPHQL_URL = DEFAULT_GRAPHQL_URL
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(GraphQLTestCase, cls).setUpClass()
|
||||
|
||||
if not cls.GRAPHQL_SCHEMA:
|
||||
raise AttributeError(
|
||||
"Variable GRAPHQL_SCHEMA not defined in GraphQLTestCase."
|
||||
)
|
||||
|
||||
cls._client = Client()
|
||||
|
||||
def query(self, query, op_name=None, input_data=None, variables=None, headers=None):
|
||||
|
@ -43,28 +93,15 @@ class GraphQLTestCase(TestCase):
|
|||
Returns:
|
||||
Response object from client
|
||||
"""
|
||||
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 = 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
|
||||
return graphql_query(
|
||||
query,
|
||||
op_name=op_name,
|
||||
input_data=input_data,
|
||||
variables=variables,
|
||||
headers=headers,
|
||||
client=self._client,
|
||||
graphql_url=self.GRAPHQL_URL,
|
||||
)
|
||||
|
||||
def assertResponseNoErrors(self, resp):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue
Block a user