Skip to main content

Overview

The Adoptme API provides mock data generation capabilities powered by @faker-js/faker (Spanish Mexican locale). This is essential for:
  • Testing: Populate test databases with realistic data
  • Development: Quickly create sample data for frontend development
  • Demonstrations: Generate demo data for presentations
  • Load Testing: Create large datasets for performance testing

Mock Generation Functions

The API includes two core functions for generating mock data:

generaPet()

Generates a random pet with realistic attributes:
import { fakerES_MX as fa } from "@faker-js/faker";
import { createHash } from "../utils/index.js";

export const generaPet = () => {
    let name = fa.animal.petName();
    let specie = fa.animal.type();
    let birthDate = fa.date.birthdate({ mode: 'age', min: 18, max: 65 });
    let adopted = fa.datatype.boolean();
    let image = fa.image.avatar();

    let pet = {
        name,
        specie,
        birthDate,
        adopted,
        image
    };

    if (adopted) {
        pet.owner = fa.person.fullName();
    }

    return { pet };
}
Generated Fields:
  • name: Random pet name (e.g., “Max”, “Luna”, “Rocky”)
  • specie: Random animal type (e.g., “dog”, “cat”, “bird”)
  • birthDate: Random birthdate (18-65 years old)
  • adopted: Boolean indicating adoption status
  • image: Random avatar URL
  • owner: Owner’s full name (only if adopted is true)

generaUser()

Generates a random user with hashed password:
export const generaUser = async () => {
    let first_name = fa.person.firstName();
    let last_name = fa.person.lastName();
    let email = fa.internet.email({
        firstName: first_name,
        lastName: last_name, 
        provider: "gmail.com"
    });
    let password = await createHash('coder123');
    let role = fa.helpers.arrayElement(['user', 'admin']);
    let pets = [];

    return {
        first_name,
        last_name,
        email,
        password,
        role,
        pets
    };
}
Generated Fields:
  • first_name: Random first name
  • last_name: Random last name
  • email: Email address based on name (always @gmail.com)
  • password: Hashed version of “coder123”
  • role: Either “user” or “admin” (random)
  • pets: Empty array (can be populated later)
All generated users have the same password: coder123 (hashed). This simplifies testing authentication flows.

Mock API Endpoints

GET /api/mocks/mockingusers

Generates mock users without persisting them to the database. Useful for previewing data structure. Query Parameters:
ParameterTypeDefaultDescription
cantidadnumber1Number of users to generate
Example Request:
GET /api/mocks/mockingusers?cantidad=5
Example Response:
{
  "usuarios": [
    {
      "first_name": "Juan",
      "last_name": "García",
      "email": "[email protected]",
      "password": "$2b$10$...",
      "role": "user",
      "pets": []
    },
    // ... 4 more users
  ]
}
Implementation:
router.get('/mockingusers', (req, res) => {
    let { cantidad } = req.query;
    
    if (cantidad < 0) {
        return res.status(400).json({ error: "Cantidad enviada debe de ser positiva" });
    }

    if (!cantidad) cantidad = 1;

    let usuarios = [];

    for (let i = 0; i < cantidad; i++) {
        usuarios.push(generaUser());
    }

    return res.status(200).json({ usuarios });
});
Negative values for cantidad will return a 400 error. Always provide positive integers.

POST /api/mocks/generateData

Generates and persists mock users and pets to the database. Adopted pets are automatically assigned to random generated users. Query Parameters:
ParameterTypeDefaultDescription
usernumber1Number of users to create
petnumber1Number of pets to create
Example Request:
POST /api/mocks/generateData?user=10&pet=20
Example Response:
{
  "message": "Datos generados exitosamente",
  "users": [
    {
      "_id": "507f1f77bcf86cd799439011",
      "first_name": "María",
      "last_name": "López",
      "email": "[email protected]",
      "role": "admin",
      "pets": []
    }
    // ... more users
  ],
  "pets": [
    {
      "_id": "507f1f77bcf86cd799439012",
      "name": "Max",
      "specie": "dog",
      "birthDate": "2020-05-15T00:00:00.000Z",
      "adopted": true,
      "owner": "507f1f77bcf86cd799439011",
      "image": "https://..."
    }
    // ... more pets
  ]
}
Implementation Details:
router.post('/generateData', async (req, res) => {
    try {
        let { user, pet } = req.query;

        user = parseInt(user) || 1;
        pet = parseInt(pet) || 1;

        if (user < 0 || pet < 0) {
            return res.status(400).json({ error: "Cantidad enviada debe de ser positiva" });
        }

        // Generate users
        let users = [];
        for (let i = 0; i < user; i++) {
            users.push(await generaUser());
        }

        // Insert users into database
        const usersInsertados = await userModel.insertMany(users);

        let pets = [];

        // Generate pets
        for (let i = 0; i < pet; i++) {
            let generaData = generaPet().pet;

            // If pet is adopted, assign a random owner from generated users
            if (generaData.adopted) {
                const randomUser = usersInsertados[Math.floor(Math.random() * usersInsertados.length)];
                generaData.owner = randomUser._id;
            }

            pets.push(generaData);
        }

        // Insert pets into database
        const petsInsertados = await petModel.insertMany(pets);

        return res.status(201).json({
            message: 'Datos generados exitosamente',
            users: usersInsertados,
            pets: petsInsertados
        });

    } catch (error) {
        console.error("Error generando datos:", error);
        return res.status(500).json({ error: "Error interno del servidor" });
    }
});
Adopted pets are automatically linked to randomly selected users from the same generation batch. This creates realistic ownership relationships.

Usage Examples

Quick Test Data Setup

1

Generate sample data

Create 5 users and 10 pets:
curl -X POST "http://localhost:8080/api/mocks/generateData?user=5&pet=10"
2

Verify data creation

Check that users were created:
curl http://localhost:8080/api/users
3

Check pet assignments

View pets and their owners:
curl http://localhost:8080/api/pets

Load Testing Scenario

Generate a large dataset for performance testing:
# Create 1000 users and 5000 pets
curl -X POST "http://localhost:8080/api/mocks/generateData?user=1000&pet=5000"

Preview Data Structure

Preview mock data without database insertion:
# Generate 3 sample users (not persisted)
curl "http://localhost:8080/api/mocks/mockingusers?cantidad=3"

Error Handling

Negative Quantities

POST /api/mocks/generateData?user=-5
Response: 400 Bad Request
{
  "error": "Cantidad enviada debe de ser positiva"
}

Server Errors

If database insertion fails: Response: 500 Internal Server Error
{
  "error": "Error interno del servidor"
}

Integration with Tests

The mock endpoints are extensively tested:
it("Si quiero generar 1 usuario y 1 mascota, al apuntar al endpoint /api/mocks/generateData metodo POST sin pasarle cantidad, da de alta 1 usuario y 1 mascota en DB", async() => {
    let {status, body} = await requester.post(`/api/mocks/generateData`).send();
    expect(status).to.be.eq(201);
    expect(Array(body));
    expect(body.message).to.be.eq("Datos generados exitosamente");
});
See the Testing Guide for more test examples.

Best Practices

  1. Use mockingusers for previews - Test data structure without database writes
  2. Use generateData for integration tests - Create realistic test scenarios
  3. Clean up after tests - Delete generated data to avoid database bloat
  4. Limit quantities in CI/CD - Large datasets can slow down automated tests
  5. Leverage default values - Omit parameters for simple single-entity creation

Faker.js Locale

The API uses @faker-js/faker with the Spanish (Mexico) locale:
import { fakerES_MX as fa } from "@faker-js/faker";
This generates culturally appropriate names, emails, and data for Spanish-speaking users.

Next Steps

Build docs developers (and LLMs) love