Автор оригинала: Jeff M Lowery.
Как поднять API GraphQL с реалистичными ценностями
В моя последняя статья Я взял оригинал Apollo Launchpad Посты и авторы API и сломал его на домены и компоненты. Я хотел проиллюстрировать, как можно организовать большой проект GraphQL, используя graphql-tools Отказ
Теперь я хотел бы API, чтобы вернуть данные Mock, когда я его запрашиваю. Как?
Оригинальный источник
В исходном примере Apollo LaunchPad мы использовали статические структуры данных и простые сопоставления резользеров для обеспечения вывода запросов.
Например, учитывая этот запрос:
# Welcome to GraphiQL
query PostsForAuthor {
author(id: 1) {
firstName
posts {
title
votes
}
}
}Вывод будет:
{
"data": {
"author": {
"firstName": "Tom",
"posts": [
{
"title": "Introduction to GraphQL",
"votes": 2
}
]
}
}
}Объект Resolvers имеет функции, которые заботятся о сопоставлении авторов к постам и Visa-Versa. Это не по-настоящему издевательство, хотя.
Проблема в том, что тем больше отношения и более сложные субъекты становятся, тем больше кодекс должен идти в резольветеры. Затем необходимо предоставить больше данных.
Когда дело доходит до тестирования, тесты могут иногда раскрывать проблемы в данных или в резольвестах. Вы действительно хотите фокус-тестирование самого API.
Используя издевательства
Существует три модуля Node.js, которые делают издевание API быстро и легко. Первое является частью graphql-tools модуль. Используя этот модуль, начальный шаг должен требовать или импортировать метод AddmockFunctionStoschema из модуля в корне schema.js файл:
import {
makeExecutableSchema,
addMockFunctionsToSchema
} from 'graphql-tools';Затем, после создания исполняемого файла Схема Призывая CreateExecutableschema , Вы добавляете свои издевательства так:
addMockFunctionsToSchema({
schema: executableSchema,
})Вот полный список корня schema.js :
// This example demonstrates a simple server with some relational data: Posts and Authors. You can get the posts for a particular author,
// and vice-versa Read the complete docs for graphql-tools here: http://dev.apollodata.com/tools/graphql-tools/generate-schema.html
import {
makeExecutableSchema,
addMockFunctionsToSchema
} from 'graphql-tools';
import {
schema as authorpostsSchema,
resolvers as authorpostsResolvers
} from './authorposts';
import {
schema as myLittleTypoSchema,
resolvers as myLittleTypeResolvers
} from './myLittleDomain';
import {
merge
} from 'lodash';
const baseSchema = [
`
type Query {
domain: String
}
type Mutation {
domain: String
}
schema {
query: Query,
mutation: Mutation
}`
]
// Put schema together into one array of schema strings and one map of resolvers, like makeExecutableSchema expects
const schema = [...baseSchema, ...authorpostsSchema, ...myLittleTypoSchema]
const options = {
typeDefs: schema,
resolvers: merge(authorpostsResolvers, myLittleTypeResolvers)
}
const executableSchema = makeExecutableSchema(options);
addMockFunctionsToSchema({
schema: executableSchema
})
export default executableSchema;Так что же вывод? Выполнение одного и того же запроса, что и доходности:
{
"data": {
"author": {
"firstName": "Hello World",
"posts": [
{
"title": "Hello World",
"votes": -70
},
{
"title": "Hello World",
"votes": -77
}
]
}
}
}Ну, это глупо. Каждая строка «Hello World», голоса негативны, и всегда будут именно два поста на авторе. Мы исправим это, но сначала …
Зачем использовать издевательства?
Макеты часто используются в модульных тестах, чтобы отделить функциональность, протестируемую от зависимостей, на которых опираются эти функции. Вы хотите проверить функцию (устройство), а не целый комплекс функций.
На этой ранней стадии разработки издевательства служат другой целью: тестировать тесты. В базовом тесте вы хотите сначала убедиться, что тест вызывает API правильно, и что возвращаемые результаты имеют ожидаемую структуру, свойства и типы. Я думаю, что крутые дети называют эту «форму».
Это предлагает более ограниченное тестирование, чем запрошенная структура данных, поскольку эталонная семантика не применяется. ID бессмысленно. Тем не менее, издевательства предлагают что-то, чтобы структурировать ваши тесты вокруг
Реалистичные издевательства
Есть модуль называется Случайные что мне очень нравится. Он обеспечивает разумные и переменные значения для многих общих типов данных. Если вы демонстрируете свой новый API перед изумившими коллегами, он на самом деле выглядит так, как вы сделали что-то особенное.
Вот список желаний для значений MOCK для отображения:
- Имя автора должно быть первым именем
- Почты должны быть переменными Lorem Ipsum Текст ограниченной длины
- голоса должны быть положительными или ноль
- Количество постов следует варьироваться от 1 до 7
Во-первых, что создать папку под названием Макеты Отказ Далее мы добавим index.js Файл к этой папке с методами издевательства. Наконец, пользовательские издевательства будут добавлены к сгенерированной исполняемой схеме.
Случайные Библиотека может генерировать значения по типу данных ( String, ID, INT, ... ) или по имени свойства. Кроме того, объект Mocklist GraphQL-Tools будет использоваться для изменения количества элементов в списке – в этом случае Сообщения Отказ Итак, начнем.
Импорт как повседневный, так и высмеист в /mocks/index.js :
import casual from 'casual';
import {
MockList
} from 'graphql-tools';Теперь позвольте создать экспорт по умолчанию со следующими свойствами:
export default {
Int: () => casual.integer(0),
Author: () => ({
firstName: casual.first_name,
posts: () => new MockList([1, 7])
}),
Post: () => ({
title: casual.title
})
} Int Декларация заботится обо всех целочисленных типах, появляющихся в нашей схеме, и она обеспечит, чтобы Post.votes будет положительным или ноль.
Далее Aper.firstname будет разумное имя. Маклист используется для обеспечения того, чтобы количество сообщений, связанных с каждым автором, будет от 1 до 7 лет, наконец, случайные будут генерировать Lorem Ipsum Название для каждого Пост Отказ
Теперь сгенерированный выход варьируется каждый раз, когда запрос выполняется. И это выглядит доверительно:
{
"data": {
"author": {
"firstName": "Eldon",
"posts": [
{
"title": "Voluptatum quae laudantium",
"votes": 581
},
{
"title": "Vero quos",
"votes": 85
},
{
"title": "Doloribus labore corrupti",
"votes": 771
},
{
"title": "Qui nulla qui",
"votes": 285
}
]
}
}
}Генерация пользовательских значений
Я только что поцарапал поверхность того, что может сделать случайным, но это хорошо документировано, и нельзя ничего добавить.
Иногда, хотя есть ценности, которые должны соответствовать стандартному формату. Я хотел бы представить еще один модуль: Randexp Отказ
Randexp позволяет создавать значения, соответствующие выражению RegexP, которое вы его предоставите. Например, номера ISBN имеют формат:
/Isbn- \ d- \ d {3} – \ d {5} – \ d/
Теперь я могу добавить книги в схему, добавлять книги к автору и генерировать ISBN и заголовок для каждого Книга :
// book.js
export default `
type Book {
ISBN: String
title: String
}mocks.js:
import casual from 'casual';
import RandExp from 'randexp';
import {
MockList
} from 'graphql-tools';
import {
startCase
} from 'lodash';
export default {
Int: () => casual.integer(0),
Author: () => ({
firstName: casual.first_name,
posts: () => new MockList([1, 7]),
books: () => new MockList([0, 5])
}),
Post: () => ({
title: casual.title
}),
Book: () => ({
ISBN: new RandExp(/ISBN-\d-\d{3}-\d{5}-\d/)
.gen(),
title: startCase(casual.title)
})
}И вот новый запрос:
query PostsForAuthor {
author(id: 1) {
firstName
posts {
title
votes
}
books {
title
ISBN
}
}
}Образец ответа:
{
"data": {
"author": {
"firstName": "Rosemarie",
"posts": [
{
"title": "Et ipsum quo",
"votes": 248
},
{
"title": "Deleniti nihil",
"votes": 789
},
{
"title": "Aut aut reprehenderit",
"votes": 220
},
{
"title": "Nesciunt debitis mollitia",
"votes": 181
}
],
"books": [
{
"title": "Consequatur Veniam Voluptas",
"ISBN": "ISBN-0-843-74186-9"
},
{
"title": "Totam Et Iusto",
"ISBN": "ISBN-6-532-70557-3"
},
{
"title": "Voluptatem Est Sunt",
"ISBN": "ISBN-2-323-13918-2"
}
]
}
}
}Так что это основы издевательства с использованием GraphQL-инструментов, а также пару других полезных модулей.
Примечание : Я использую фрагменты на протяжении всего этого поста. Если вы хотите следовать в более широком контексте, образец кода – здесь Отказ
Полный источник находится на Github для вашего прочтения.
Дайте мне руку, если вы нашли эту статью информативную.