* Added test class for django api unittests and documentation how to use it

This commit is contained in:
Ronny Vedrilla 2019-03-29 11:51:40 +01:00
parent ea2cd9894f
commit b491878c27
3 changed files with 125 additions and 0 deletions

View File

@ -14,3 +14,4 @@ Contents:
rest-framework
form-mutations
introspection
testing

60
docs/testing.rst Normal file
View File

@ -0,0 +1,60 @@
Testing API calls with django
=============================
If you want to unittest your API calls derive your test case from the class `GraphQLTestCase`.
Usage:
.. code:: python
import json
from graphene_django.tests.base_test 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(
'''
query {
myModel {
id
name
}
}
''',
op_name='myModel'
)
content = json.loads(response.content)
# This validates the status code and if you get errors
self.assertResponseNoErrors(response)
# Add some more asserts if you like
...
def test_some_mutation(self):
response = self.query(
'''
mutation myMutation($input: MyMutationInput!) {
myMutation(input: $input) {
my-model {
id
name
}
}
}
''',
op_name='myMutation',
input_data={'my_field': 'foo', 'other_field': 'bar'}
)
# This validates the status code and if you get errors
self.assertResponseNoErrors(response)
# Add some more asserts if you like
...

View File

@ -0,0 +1,64 @@
import json
from django.http import HttpResponse
from django.test import Client
from django.test import TestCase
class GraphQLTestCase(TestCase):
"""
Based on: https://www.sam.today/blog/testing-graphql-with-graphene-django/
"""
# URL to graphql endpoint
GRAPHQL_URL = '/graphql/'
# Here you need to set your graphql schema for the tests
GRAPHQL_SCHEMA = None
@classmethod
def setUpClass(cls):
super().setUpClass()
if not cls.GRAPHQL_SCHEMA:
raise AttributeError('Variable GRAPHQL_SCHEMA not defined in GraphQLTestCase.')
cls._client = Client(cls.GRAPHQL_SCHEMA)
def query(self, query: str, op_name: str = None, input_data: dict = 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
Returns:
Response object from client
"""
body = {'query': query}
if op_name:
body['operation_name'] = op_name
if input_data:
body['variables'] = {'input': input_data}
resp = self._client.post(self.GRAPHQL_URL, json.dumps(body),
content_type='application/json')
return resp
def assertResponseNoErrors(self, resp: HttpResponse):
"""
Assert that the call went through correctly. 200 means the syntax is ok, if there are no `errors`,
the call was fine.
"""
content = json.loads(resp.content)
self.assertEqual(resp.status_code, 200)
self.assertNotIn('errors', list(content.keys()))
def assertResponseHasErrors(self, resp: HttpResponse):
"""
Assert that the call was failing. Take care: Even with errors, GraphQL returns status 200!
"""
content = json.loads(resp.content)
self.assertIn('errors', list(content.keys()))