Skip to main content

Tutorial

Let's discover [mocq] in less than 5 minutes

Getting Started

For this tutorial we will be working with these two types User and Node

type User = {
username: string
email: string
};

type Node = {
name: string
createdBy: string
};

In this contrived example Nodes are created by Users

The goal of this tutorial will be:

  • generate mock Users & Nodes
  • connect Node data with User data, ensuring every Node is created by a valid User in our data set
  • explore using handlers to do something with this resolved data

Generating Data

First we'll define some data generator functions

/generators.js
export const generateMockUser = (i) => {
const username = `user_${i}`;
return {
username,
email: `${username}@email.com`,
};
};

export const generateMockNode = (i) => ({
name: `node_${i}`,
createdBy: 'unknown',
});

These functions create a singe instance of Node & User type, and are handed index for use with uniqueness

Now we define our configuration object, we'll make 25 Users and 100 Nodes using the generator functions we wrote above

We'll use the configuration key names users and nodes for our User and Node data type configurations to maintain context

/index.js
import { mocq } from 'mocq';
import { generateMockUser, generateMockNode } from './generators';

const config = {
users: {
generator: generateMockUser,
count: 25,
},
nodes: {
generator: generateMockNode,
count: 100,
},
};

const { generate } = mocq(config);

const { data: { users, nodes } } = generate();

Sample Resolved Data

users:

[
{
username: 'user_0'
email: 'user_0@email.com'
},
// ... 24 more entries
]

nodes:

[
{
name: 'node_0'
createdBy: 'unkown'
},
// ... 99 more entries
]

Connecting Data

Now we'll define our connection function, this function will assign a random User username to the createdBy value for each Node

/connections.js
export const userCreatedNodeConnection = (users) => {
const randomIndex = Math.floor(Math.random() * users.length);
return {
createdBy: users[randomIndex].username,
};
};

Again this function is utilized at the instance level, we are given the resolved data from the users config

we also have access to the index and the data of the current Node instance being manipulated however those won't be needed in our example (see API for full spec)

Let's add the connection to the nodes configuration under connections with the key users to enable the function to hook into the users config resolved data

/index.js
import { mocq } from 'mocq';
import { generateMockUser, generateMockNode } from './generators';
import { userCreatedNodeConnection } from './connections';

const config = {
users: {
generator: generateMockUser,
count: 25,
},
nodes: {
generator: generateMockNode,
count: 100,
connections: {
users: userCreatedNodeConnection,
};
},
};

const { generate } = mocq(config);

const { data: { users, nodes } } = generate();

Sample Resolved Data

users:

[
{
username: 'user_0'
email: 'user_0@email.com'
},
// ... 24 more entries
]

nodes:

[
{
name: 'node_0'
createdBy: 'user_7'
},
{
name: 'node_1'
createdBy: 'user_3'
},
// ... 98 more entries
]

Handling Resolved Data

Our data is now generating correctly

In our simple example it's very easy to see that Users need to be defined before Nodes in order for the createdBy field to properly reference generated Users

However for larger data sets with many types of objects this order of operations might not be as apparent

That's where handlers come in to play, allowing you to execute a function against resloved data utilizing the derived execution order used to generate the data

Meaning whether you're writing this data to a database, calling an api, or whatever; handler functions will be executed in an order allowing parent data to be defined 1st enabling data to seemless flow into your data store

In this example we will simply log the output with our handler function

note

handler functions can be sync or async

/handlers.js
export const logHandler = (data) => {
data.map(x => console.log(x));
};

Now lets add this handler to our configuration

we'll flip the order of our configuration keys to show the execution order coordination in action

/index.js
import { mocq } from 'mocq';
import { generateMockUser, generateMockNode } from './generators';
import { userCreatedNodeConnection } from './connections';
import { logHandler } from './handlers';

const config = {
nodes: {
generator: generateMockNode,
count: 100,
connections: {
users: userCreatedNodeConnection,
};
handler: logHandler,
},
users: {
generator: generateMockUser,
count: 25,
handler: logHandler,
},
};

const { execute } = mocq(config);

const { data: { users, nodes } } = await execute();

Sample Output

{
username: 'user_0'
email: 'user_0@email.com'
}
{
username: 'user_1'
email: 'user_1@email.com'
}
// ... 23 more entries
{
name: 'node_0'
createdBy: 'user_18'
}
{
name: 'node_1'
createdBy: 'user_2'
}
// ... 98 more entries
Congratulations

🎉 You have completed the [mocq] tutorial 🎉

You should have all the tools you need to start coding but if not check out the docs or browse the examples for more 🚀