Django GraphQL Test: How to test addition of new model fields?

Viewed 333

I have a simple model as,

class Person(models.Model):
    first_name = models.CharField(max_length=20)

and I have setup the GraphQL to query the data,

import graphene
import graphene_django
from .models import Person


class PersonType(graphene_django.DjangoObjectType):
    class Meta:
        model = Person
        fields = '__all__'


class PersonQuery(graphene.ObjectType):
    persons = graphene.List(PersonType)

    def resolve_persons(*args, **kwargs):
        return Person.objects.all()

So far so good. Later I decided to write unittests for querying the persons data

from django.test import TestCase
from .models import Person
from .schema import schema


class TestGraphQLQuery(TestCase):

    @classmethod
    def setUpTestData(cls):
        cls.person = Person.objects.create(first_name="Jack")

    def test_person_query(self):
        query = """
            query{
              persons {
                id
                firstName
              }
            }
        """
        result = schema.execute(query).data
        expected = {'persons': [{'id': f'{self.person.pk}', 'firstName': self.person.first_name}]}
        self.assertEqual(result, expected)

and this too working.

Later, my model got updated with one additional field, age,

class Person(models.Model):
    first_name = models.CharField(max_length=20)
    age = models.IntegerField(default=0)

After the changes, I ran the unittests. As expected, it passes.

Question

How can I create the test case so that, the test should fail upon addition or removal of any fields?

Advantages of this test cases that I am seeking

  1. We will get notified whenever a new field added to the model
  2. We will get notified whenever a field removed or renamed
  3. Generating dynamic graphql query will also help to verify the returned data from the schema.
2 Answers

We can use the introspection query to get the fields of a specific type.

from django.test import TestCase
from .models import Person
from .schema import schema


class TestGraphQLQuery(TestCase):

    @classmethod
    def setUpTestData(cls):
        cls.person = Person.objects.create(first_name="Jack")

    def test_person_query(self):
        introspection_query = """
            {
               __type(name:"PersonType") {
                  fields {
                     name
                  }  
               }
            }
        """
        introspection_result = schema.execute(introspection_query).data["__type"]["fields"]
        introspection_expected = [{'name': 'id'}, {'name': 'firstName'}, {'name': 'age'}]
        self.assertCountEqual(introspection_result, introspection_expected)

        dynamic_person_fields = "\n".join([item['name'] for item in introspection_result])
        data_query = f"""
            query{{
              persons {{
                {dynamic_person_fields}
              }}
            }}
        """
        data_result = schema.execute(data_query).data["persons"]
        data_expected = [{'id': f'{self.person.pk}', 'firstName': self.person.first_name, 'age': self.person.age}]
        self.assertEqual(data_result, data_expected)

Reference

Related