
Product
Introducing Webhook Events for Alert Changes
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.
@4c/graphql-mocking
Advanced tools
Quickly mock out any GraphQL API with examples and augmented with smart autogenerated data.
Quickly mock out any GraphQL API with examples and augmented with smart autogenerated data.
At a high level graphql-mocking is just a graphql-js "server" that processes
a request and resolves an return value. Instead of sourcing the data from an API
or other backend, it uses an in memory graphql (like a simple ORM) built from
example data and data generated from type information.
The core export of graphql-mocking is a MockStore instance which encapsulates
a mocked GraphQL schema and the in memory data.
import Mocks from '@4c/graphql-mocking';
import graphql from from 'graphql';
const store = new Mocks(`
type Root {
person(id: ID): Person
}
type Person {
name: String
}
schema {
query: Root
}
`)
const result = await graphql(store.mockedSchema, `
query {
person(id: 1) {
name
}
}
`);
Without any additional configuration mockedSchema will resolve valid
queries with seed generated data. Even better, a number of common
schema patterns will be implemented automatically, such as Relay style
Connections with pagination.
Since testing UIs backed by a GraphQL server is a main use case. It's not sufficient to simply generate randon data. Data that changes every run makes for bad tests. To avoid this each field has access to a "seeded" data generator, which means data will be consistently generated for that field every time a resolution is run.
Generally fully generated data isn't sufficient for most mocking. Eventually you want to add specific examples and custom mocking. To accomplish this we need to introduce two concepts:
Mocks control schema resolution logic. They are similar
in spirit to a GraphQL field resolver, expect they have a different "pivot".
Normally a resolver is defined per field. A schema have many different
types with the Person field type, and each one defines it's own resolver
from the source object. Mocks, work per type instead, meaning you can define
how *any Person is resolved regardless of it's parent type.
This is a powerful way to define schema behavior without needing to clarify behavior for every usage of a type in your schema. For instance we can implement a lookup for fields with arguments:
// fake data
const people = {
1: { name: 'James' },
2: { name: 'Besty' },
};
// Mock the 'person' field on the tooy Query type
store.mock('Query', () => ({
person: (args, context, info) => people[args.id],
}));
const result = await graphql(
store.mockedSchema,
gql`
query {
person(id: 1) {
name
}
}
`,
);
result.data.person; // { name: 'James' }
Mocks return a "source" object used by GraphQL to resolve the
value of the type, you are mocking. For an overview of what this
entails we suggest reading: https://graphql.org/graphql-js/object-types/
but quickly, mocks can return a concrete value, as in the case of scalars
like String, Boolean, etc. Or an object with functions that return a
concrete value.
store.mock('String', () => 'hello world'); // 'hello world' will be used for all strings
store.mock('Person', () => ({
name: () => generateName(),
}));
AS seen in the person example above. Mock field resolvers are also based
the field arguments as well as the graphql context and info objects.
Examples are static data for a graphql type, think of it as the data from
your database that provides the source objects for GraphQL resolution. For
instance the following are "examples" of a Person from our schema:
const people = store.addExamples('Person', [
{
id: 'a575bf7b-3eda-4015-98f9-6077a68a91e8',
name: 'James',
age: 68,
},
{
id: 'e78ac19b-6d06-401e-9ff4-6a4f20dea718',
name: 'Betsy',
age: 42,
},
]);
When you add examples, they are used as a pool to pull from when resolving types. Examples don't need to be conprehensive, any fields in the GQL type that don't have a corresponding example field will be generated normally.
Examples often differ structurally from the GraphQL type they resolve to!
For instance our Person might look like:
type Person {
id: ID
personId: String
name: String!
isRetirementAge: Boolean
}
Here instead of exposing age directly, Person defines isRetirementAge which
is derived from age. However, when we try and add an example with age we get
an error:
store.addExample('Person', {
id: 'e78ac19b-6d06-401e-9ff4-6a4f20dea718',
name: 'Betsy',
age: 42,
});
// TypeError: `age does not exist on type Person`
This is helpful guardrail to ensure that our mock data is explicit
about which properties map to GraphQL fields. If we want to
explicitly deviate we need to prefix our field with $ to mark it
as "internal".
store.addExample('Person', {
id: 'e78ac19b-6d06-401e-9ff4-6a4f20dea718',
name: 'Betsy',
$age: 42,
});
Now we can pair our example with a Mock to derive the correct
value for isRetirementAge.
const store = new Mocks(schema);
store.addExample('Person', {
id: 'e78ac19b-6d06-401e-9ff4-6a4f20dea718',
name: 'Betsy',
age: 42,
});
store.mock('Person', () => ({
isRetirementAge() {
// this is the source object in a graphql resolver
this.$age >= 65;
},
}));
Examples provide the mocked schema with concrete values to use
when resolving types, as well as defining relationships between
data in the graph. As with databases, examples should provide a
primary key (by default either id or $id). Pks are used to create explicit
relationships between other examples in the graph.
Consider the following schema defniing Person and blog Post:
type Post {
id: ID
title: String
content: String
}
type Person {
id: ID
name: String!
posts: [Post]
}
If we wanted to add examples that defined links we could do so like:
store.addExample('Person', [
{
id: 'person1',
name: 'James',
},
{
id: 'person2',
name: 'Betsy',
},
]);
store.addExamples('Post', [
{
id: 'post1',
$personId: 'person1',
title: 'Building a graphql mocking library',
},
{
id: 'post2',
$personId: 'person1',
title: 'Funny looking birds',
},
{
id: 'post3',
$personId: 'person2',
title: 'The Ultimate Answer',
},
]);
Now we can relate these two types with a mock using the built-in related helper
import { related } from '@4c/graphql-mocking';
store.mock('Person', () => ({
posts: related({
relatedFieldName: '$personId',
idField: '$id',
}),
}));
now when we query for posts on people it will "Just Work"
const result = await graphql(
store.mockedSchema,
gql`
query {
person(id: "person1") {
name
posts {
title
}
}
}
`,
);
// results in
data: {
person: {
name: 'James',
posts: [
{ title: 'Building a graphql mocking library' },
{ title: 'Funny looking birds' }
]
}
}
(This works for one-to-many or one-to-one relationships equally well).
Because this is such a common pattern, the library will automatically set up these relationships if it can infer from the example and type.
Heads: Internal keys that end with
Idare automatically considered foreign key to it's connected type.
The mocking is also smart enough to infer fields as foreign keys
if the schema type for the field is an object type and the example value
is a string, it will assume it's an id reference.
store.addExamples('Post', [
{
$id: 'post1',
person: 'person1',
title: 'Building a graphql mocking library',
},
No other configuration needed.
graphql-mocking, comes with out of the box support for Relay schema additions, which include:
When the schema has a Node interface and node query field, graphql-mocking
will automatically mock them to work with example data.
query {
node(id: "RmlsbToy") {
... on Person {
name
}
}
}
In addition a specialized ID scalar mock is configured to return Relay compatible "global Ids",
which are base64 encodings of the type name and local identifier. Note this requires that
examples use a different field for their id than id, we recommend $id since it works out
of the box.
store.addExample('Person', [
{
$id: 'person1',
name: 'James',
},
{
$id: 'person2',
name: 'Betsy',
},
]);
const result = await graphql(
store.mockedSchema,
gql`
query {
people {
name
}
}
`,
);
Pagination with connections also works out of the box just like List type
generation and inference. Connections can also be configured directly via:
import { connection } from '@4c/graphql-mocking/relay';
store.mock('Person', {
postConnection: connection({ relatedIdField: '$personId' }),
});
FAQs
Quickly mock out any GraphQL API with examples and augmented with smart autogenerated data.
We found that @4c/graphql-mocking demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.

Security News
ENISA has become a CVE Program Root, giving the EU a central authority for coordinating vulnerability reporting, disclosure, and cross-border response.

Product
Socket now scans OpenVSX extensions, giving teams early detection of risky behaviors, hidden capabilities, and supply chain threats in developer tools.