@mocking-bird/graphql
v1.2.2
Published
GraphQL fixture generation library that generates mock data based on the GraphQL schema and TypedDocumentNodes. A graphql fixture consists of two different data types:
Downloads
3
Maintainers
Readme
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
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
->[email protected]
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
GraphQLFixtureOptions
| name | type | default | description |
| ------------------------- | ---------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------ |
| ignoreCustomScalars
| boolean
| false
| Whether to ignore custom scalar types or not |
| addTypeName
| boolean
| false
| Whether to add type names in mock query or mutations |
| scalarDefinitions
| Record<string, ScalarDefinition>
| undefined
| Custom scalar definitions |
| fieldRelations
| Record<FieldPath, FieldPath>
, Record<FieldPath, FieldPath[]>
| undefined
| Field relation map. If specified related fields are assigned same values |
| rules
| Rule[]
| undefined
| Custom rules to apply for fixture generation |
| exclude
| FieldPath[]
| undefined
| Fields to exclude from fixture generation |
| requiredOnly
| boolean
| false
| Whether to generate only the required fields or not |
| isAccurate
| boolean
| true
| Should employ accurate data generation based on field names |
Rule
| name | type | isRequired | description |
| -------------- | ---------------------- | ---------- | ------------------------------------------------------------------------------------------ |
| path
| FieldPath
| true
| The path to the field, for which the rule applies |
| required
| boolean
| false
| Is the field required or not |
| size
| number
| false
| The size of the generated value, which may apply to arrays, strings or numbers |
| min
| number
| false
| The min value of the generated value. For arrays or strings the minimum size. |
| max
| number
| false
| The max value of the generated value. For arrays or string the maximum size. |
| enum
| string[]
, number[]
| false
| The enum to apply for the generated value |
| pattern
| RegExp
| false
| The 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 asaddress.street
. It can also be a wildcard path, such asaddress.*
, which means all fields underaddress
.
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
anddata
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
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
You can override the generated values by providing a map of values to override:
fixture.generate({
name: 'John Doe',
email: '[email protected]',
age: 25,
});
// or using wildcards
fixture.generate({
'address.**.buildingNo': '1234',
});