What is @anatine/zod-mock?
@anatine/zod-mock is an npm package that provides utilities for generating mock data based on Zod schemas. It is particularly useful for testing and development purposes where you need to create consistent and realistic mock data that adheres to your Zod schema definitions.
What are @anatine/zod-mock's main functionalities?
Generate Mock Data
This feature allows you to generate mock data based on a Zod schema. In this example, a user schema is defined with an id, name, and age. The `mock` function generates a mock user object that adheres to this schema.
const { z } = require('zod');
const { mock } = require('@anatine/zod-mock');
const userSchema = z.object({
id: z.string().uuid(),
name: z.string(),
age: z.number().int().min(18).max(99)
});
const mockUser = mock(userSchema);
console.log(mockUser);
Custom Mock Generators
This feature allows you to set custom mock generators for specific Zod types. In this example, a custom UUID generator is set, and the `mock` function uses this custom generator when creating the mock user object.
const { z } = require('zod');
const { mock, setMock } = require('@anatine/zod-mock');
const userSchema = z.object({
id: z.string().uuid(),
name: z.string(),
age: z.number().int().min(18).max(99)
});
setMock(z.string().uuid(), () => 'custom-uuid');
const mockUser = mock(userSchema);
console.log(mockUser);
Nested Schemas
This feature supports generating mock data for schemas with nested objects. In this example, a user schema includes an address schema, and the `mock` function generates a mock user object with a nested address object.
const { z } = require('zod');
const { mock } = require('@anatine/zod-mock');
const addressSchema = z.object({
street: z.string(),
city: z.string(),
zipCode: z.string().length(5)
});
const userSchema = z.object({
id: z.string().uuid(),
name: z.string(),
age: z.number().int().min(18).max(99),
address: addressSchema
});
const mockUser = mock(userSchema);
console.log(mockUser);
Other packages similar to @anatine/zod-mock
faker
Faker is a popular library for generating fake data. It provides a wide range of data types and is highly customizable. Unlike @anatine/zod-mock, Faker does not integrate directly with Zod schemas but offers more extensive data generation capabilities.
chance
Chance is another library for generating random data. It is lightweight and easy to use, offering a variety of data types. Similar to Faker, Chance does not integrate with Zod schemas but is useful for generating random data for testing purposes.
test-data-bot
Test Data Bot is a library for generating test data using a builder pattern. It allows for the creation of complex data structures and is highly customizable. While it does not integrate with Zod schemas, it provides a flexible way to generate test data.
@anatine/zod-mock
Generates a mock data object using faker.js from a Zod schema.
Installation
Both openapi3-ts and zod are peer dependencies instead of dependant packages.
While zod
is necessary for operation, openapi3-ts
is for type-casting.
npm install @faker-js/faker zod @anatine/zod-mock
Usage
Take any Zod schema and create mock data
import { generateMock } from '@anatine/zod-mock';
const schema = z.object({
uid: z.string().nonempty(),
theme: z.enum([`light`, `dark`]),
email: z.string().email().optional(),
phoneNumber: z.string().min(10).optional(),
avatar: z.string().url().optional(),
jobTitle: z.string().optional(),
otherUserEmails: z.array(z.string().email()),
stringArrays: z.array(z.string()),
stringLength: z.string().transform((val) => val.length),
numberCount: z.number().transform((item) => `total value = ${item}`),
age: z.number().min(18).max(120),
});
const mockData = generateMock(schema);
This will generate mock data similar to:
{
"uid": "3f46b40e-95ed-43d0-9165-0b8730de8d14",
"theme": "light",
"email": "Alexandre99@hotmail.com",
"phoneNumber": "1-665-405-2226",
"avatar": "https://cdn.fakercloud.com/avatars/olaolusoga_128.jpg",
"jobTitle": "Lead Brand Facilitator",
"otherUserEmails": [
"Wyman58@example.net",
"Ignacio_Nader@example.org",
"Jorge_Bradtke@example.org",
"Elena.Torphy33@example.org",
"Kelli_Bartoletti@example.com"
],
"stringArrays": [
"quisquam",
"corrupti",
"atque",
"sunt",
"voluptatem"
],
"stringLength": 4,
"numberCount": "total value = 25430",
"age": 110
}
Overriding string mocks
Sometimes there might be a reason to have a more specific mock for a string value.
You can supply an options field to generate specific mock data that will be triggered by the matching key.
const schema = z.object({
locked: z.string(),
email: z.string().email(),
primaryColor: z.string(),
});
const mockData = generateMock(schema, {
stringMap: {
locked: () => `this return set to the locked value`,
email: () => `not a email anymore`,
primaryColor: () => faker.internet.color(),
},
});
Adding a seed generator
For consistent testing, you can also add in a seed or seed array.
const schema = z.object({
name: z.string(),
age: z.number(),
});
const seed = 123;
const first = generateMock(schema, { seed });
const second = generateMock(schema, { seed });
expect(first).toEqual(second);
Adding a custom mock mapper
Once drilled down to deliver a string, number, boolean, or other primitive value a function with a matching name is searched for in faker.
You can add your own key/fn mapper in the options.
export function mockeryMapper(
keyName: string,
fakerInstance: Faker
): FakerFunction | undefined {
const keyToFnMap: Record<string, FakerFunction> = {
image: fakerInstance.image.url,
imageurl: fakerInstance.image.url,
number: fakerInstance.number.int,
float: fakerInstance.number.float,
hexadecimal: fakerInstance.number.hex,
uuid: fakerInstance.string.uuid,
boolean: fakerInstance.datatype.boolean,
email: () => fakerInstance.database.mongodbObjectId() + '@example.com'
};
return keyName && keyName.toLowerCase() in keyToFnMap
? keyToFnMap[keyName.toLowerCase() as never]
: undefined;
}
const schema = z.object({
locked: z.string(),
email: z.string().email(),
primaryColor: z.string(),
});
const result = generateMock(schema, { mockeryMapper });
Behind the Scenes
zod-mock
tries to generate mock data from two sources.
-
Object key name ie({ firstName: z.string() }
)
This will check the string name of the key against all the available faker
function names.
Upon a match, it uses that function to generate a mock value.
-
Zodtype ie(const something = z.string()
)
In the case there is no key name (the schema doesn't contain an object) or there is no key name match,
zod-mock
will use the primitive type provided by zod
.
Some zod filter types (email, uuid, url, min, max, length) will also modify the results.
If zod-mock
does not yet support a Zod type used in your schema, you may provide a backup mock function to use for that particular type.
const schema = z.object({
anyVal: z.any()
});
const mockData = generateMock(schema, {
backupMocks: {
ZodAny: () => 'a value'
}
});
Missing Features
- No pattern for passing options into
faker
, such as setting phone number formatting - Does not handle the following Zod types:
- ZodAny
- ZodDefault
- ZodFunction
- ZodIntersection
- ZodMap
- ZodPromise
- ZodSet
- ZodTuple
- ZodUnion
- ZodUnknown
Credits
This library is part of a nx monorepo @anatine/zod-plugins.