Django GraphQL测试:如何测试新模型字段的添加? 参考

问题描述

我有一个简单的模型,

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

我已经设置了GraphQL来查询数据,

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()

到目前为止一切顺利。后来我决定编写单元测试来查询persons数据

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)

这也是可行的。

后来,我的模型更新了一个附加字段, age

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

更改后,我进行了单元测试。正如预期的那样,它通过了。

问题

如何创建测试用例,以便在添加删除任何字段时测试失败?

我正在寻找的这个测试用例的优点

  1. 只要将新字段添加到模型中,我们就会收到通知
  2. 只要字段被删除重命名
  3. ,我们都会收到通知
  4. 生成 动态graphql查询 还将有助于验证从架构返回的数据。

解决方法

如果需要监视Django模型更改,则Django已经具有以下功能:https://docs.djangoproject.com/en/3.1/ref/django-admin/#cmdoption-makemigrations-check

无论何时进行验证(已检查)的模型更改,都应使用makemigrations命令将其作为迁移脚本持久化。然后,django-admin makemigrations --check将这些迁移脚本用作参考点,以检查是否存在模型突变(即添加/更改/删除的字段)。

,

我们可以使用自省查询来获取特定类型的字段。

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)

参考