graphene-djangoで定義したやつをテストしてみる その1

気になったのでちょっとだけやってみた。

参考リンク: graphene-django/test_query.py at master · graphql-python/graphene-django · GitHub

準備

Djangoの適当なプロジェクトにBookとAuthorというモデルを準備しました。

from django.db import models


class Book(models.Model):
    """本マスタ."""

    title = models.CharField(verbose_name="タイトル", blank=False, max_length=255)
    author = models.ForeignKey('Author', on_delete=models.CASCADE)


class Author(models.Model):
    """著者マスタ."""

    name = models.CharField(verbose_name="名前", blank=False, max_length=255)

schema定義を行います。 book.schema に以下のように定義しました。

import graphene
from graphene_django.types import DjangoObjectType
from .models import Book, Author


class BookType(DjangoObjectType):
    """Bookの型設定."""

    class Meta:
        model = Book


class AuthorType(DjangoObjectType):
    """Authorの型設定."""

    class Meta:
        model = Author


class Query:
    """各Queryを定義する."""

    book = graphene.Field(BookType)

    def resolve_book(self, info):
        """本の情報を返す."""
        return Book.objects.last()

app.schemaapp.settings にもSchema関連の定義を忘れずに。

import graphene
import book.schema


class Query(book.schema.Query,
            graphene.ObjectType):
    """
    各Appで定義したQueryを読み込み、GraphQLで使うQueryスキーマを作成する.
    """


schema = graphene.Schema(query=Query)
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'graphene_django',
    'book',
]

GRAPHENE = {"SCHEMA": "app.schema.schema"}

テストを書く

簡単なQueryのテストを書いてみます。

from model_bakery import baker
from django.test.testcases import TestCase

from app.schema import schema


class BookQueryTest(TestCase):

    def setUp(self):
        super().setUp()
        # model-bakerでレコードを作成する
        author = baker.make('Author', name="Soseki Natsume")
        baker.make('Book', title="I am a cat", author=author)
        # テスト用のqueryを作成
        self.query = """
            query {
                book {
                    title
                    author {
                      name
                    }
                }
            }
        """

    def test_it(self):
        # 用意したqueryをapp.schemaの定義で実行します
        result = schema.execute(self.query)
        expected = {
            "book": {
                "title": "I am a cat",
                "author": {
                    "name": 'Soseki Natsume'
                }
            }
        }

        self.assertIsNone(result.errors)
        self.assertDictEqual(expected, result.data)

テスト実行してみた

(venv) kai@~/Github/gql_playground/app
2020-01-30 23:24:36 python manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.004s

OK
Destroying test database for alias 'default'...

無事OK牧場

expected を少し変えてNGにしてみる。

        expected = {
            "book": {
                "title": "I am a cat!",
                "author": {
                    "name": 'Soseki Natsume'
                }
            }
        }

ちゃんとNGになっている。

AssertionError: {'book': {'title': 'I am a cat!', 'author': {'name': 'Soseki Natsume'}}} != {'book': {'title': 'I am a cat', 'author': {'name': 'Soseki Natsume'}}}
- {'book': {'author': {'name': 'Soseki Natsume'}, 'title': 'I am a cat!'}}
?                                                                     -

+ {'book': {'author': {'name': 'Soseki Natsume'}, 'title': 'I am a cat'}}

どこまでテストするか考えなきゃな。 明日はスナップショットテストやります。

毎日少しずつでもやるのが大事かもしれない。