1.2.2 • Published 1 year ago

@mocking-bird/graphql v1.2.2

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

GraphQL Fixture

GraphQL fixture generation library that generates mock data based on the GraphQL schema and TypedDocumentNodes. A graphql fixture consists of two different data types:

  • Variables: The input variables for the query or mutation.
  • Data: The output data from the query or mutation.

The library generates mock data from typed document nodes, which are fully typed GraphQL document nodes. Therefore, it's advised to use graphql-codegen to generate the typed document nodes.

Table of contents

Installation

npm i -D @mocking-bird/graphql

Usage

1. Parsing GraphQL schema

Parsing the schema from the GraphQL schema string:

import { GraphQLFixture } from '@mocking-bird/graphql';

const typeDefs = `
  type User {
    name: String
    email: String
    age: Int
    workEmail: String
    address: Address
    createdAt: Date
    updatedAt: Date
  }

  type Address {
    street: String
    city: String
    country: String
  }
`;

GraphQLFixture.registerSchema(typeDefs);

Parsing the schema from a file:

import { GraphQLFixture } from '@mocking-bird/graphql';

GraphQLFixture.registerSchemaFromFile('path/to/schema.graphql');

2. Generating fixtures

import { GraphQLFixture } from '@mocking-bird/graphql';

/**
 * TypedDocumentNode generated by graphql-codegen:
 *
 * export const GetQueryDocument: TypedDocumentNode<GetQuery, GetQueryVariables> = {
 *  kind: 'Document',
 *  definitions: [
 *    kind: 'OperationDefinition',
 *    operation: 'query',
 *    name: { kind: 'Name', value: 'GetQuery' },
 *    ...
 *  ]
 * }
 */

const fixture = new GraphQLFixture(GetQueryDocument);
fixture.generate();

Accurate data generation

(Back to top)

Generated data are not only random-random but also contextually accurate based on field names and types. It leverages the fuzzy search, or formally, approximate string search algorithm to search for the suitable faker to generate realistic data that relate to the field.

For example:

  • workEmail -> Jerome.Mraz58@yahoo.com
  • employeePhoneNumber -> 550-459-6013
  • uploadedFileName -> file-1234.pdf

Of course, there are still some limitations when it comes to complex field names with multiple parts, in which case the default fakers are applied. The default fakers are fallbacks in case the fuzzy search score is not high enough. The default fakers may return, depending on the field type, a random string, number, or date, and so on.

Options

(Back to top)

GraphQLFixtureOptions

nametypedefaultdescription
ignoreCustomScalarsbooleanfalseWhether to ignore custom scalar types or not
addTypeNamebooleanfalseWhether to add type names in mock query or mutations
scalarDefinitionsRecord<string, ScalarDefinition>undefinedCustom scalar definitions
fieldRelationsRecord<FieldPath, FieldPath>, Record<FieldPath, FieldPath[]>undefinedField relation map. If specified related fields are assigned same values
rulesRule[]undefinedCustom rules to apply for fixture generation
excludeFieldPath[]undefinedFields to exclude from fixture generation
requiredOnlybooleanfalseWhether to generate only the required fields or not
isAccuratebooleantrueShould employ accurate data generation based on field names

Rule

nametypeisRequireddescription
pathFieldPathtrueThe path to the field, for which the rule applies
requiredbooleanfalseIs the field required or not
sizenumberfalseThe size of the generated value, which may apply to arrays, strings or numbers
minnumberfalseThe min value of the generated value. For arrays or strings the minimum size.
maxnumberfalseThe max value of the generated value. For arrays or string the maximum size.
enumstring[], number[]falseThe enum to apply for the generated value
patternRegExpfalseThe pattern to apply for the generated value. The generated value will adhere to the regex

FieldPath

FieldPath is a string that represents the path of a field in the schema. It can be a nested path, such as address.street. It can also be a wildcard path, such as address.*, which means all fields under address.

Example

fixture.generate(
  {},
  {
    exclude: ['createdAt', 'updatedAt'],
    isAccurate: false,
    requiredOnly: true,
    rules: [
      {
        path: 'address.city',
        enum: ['Berlin', 'Frankfurt'],
      },
      {
        path: 'age',
        min: 18,
        max: 60,
      },
      {
        path: 'workEmail',
        pattern: /@gmail.com$/,
      },
    ],
  },
);

Custom Scalar Definitions

By default, the library supports Date, DateTime and JSON scalar types. You can add custom scalar definitions by:

GraphQLFixture.setGlobalOptions({
  scalarDefinitions: {
    BeforeChristDate: {
      type: FieldType.DATE,
      defaultValue: '2021-01-01',
    },
  },
});

Field Relations

Defining field relations are useful, if you want to assign the same value to related fields. For example:

const fixture = new GraphQLFixture(GetQueryDocument, {
  fieldRelations: {
    'variables.user.id': 'data.user.id',
  },
});

Note: if you are matching fields, you should use the variables and data prefixes to the field path.

In this example, generated mock variable user.id will be assigned to the generated mock data user.id. This makes sense because the id field in the variables and data should be the same.

Resolving paths

(Back to top)

When working with nested data structures, you may want to resolve the paths to the fields. This is especially useful when you want to exclude or apply rules to fields that are nested.

fixture.generate({}, { exclude: ['address.city'] });

You can also use wildcard paths to exclude or apply rules to all fields under a certain path:

fixture.generate({}, { exclude: ['address.*'] });

fixture.generate({
  'person.*.jobTitle': 'Software Engineer',
});

fixture.generate({
  'person.**.is*': true,
}); // will override every field that starts with `is` to true, e.g., isDefault, isCool etc...

Overriding values

(Back to top)

You can override the generated values by providing a map of values to override:

fixture.generate({
  name: 'John Doe',
  email: 'test@example.com',
  age: 25,
});

// or using wildcards

fixture.generate({
  'address.**.buildingNo': '1234',
});
1.2.2

1 year ago

1.2.1

1 year ago