DEV Community

aissam
aissam

Posted on

Meet Mongoose Test Factory!

Stop Writing Mock Data by Hand - Meet Mongoose Test Factory!

Are you tired of writing endless lines of mock data for your MongoDB tests? What if I told you there's a way to generate realistic test data with literally ZERO configuration?

The Problem We All Face

// We've ALL written this boring code... const mockUser = { name: "John Doe", email: "john@example.com", age: 25, isActive: true, // ... 50 more fields }; const anotherMockUser = { name: "Jane Smith", email: "jane@example.com", age: 30, // Copy-paste-modify hell continues... }; 
Enter fullscreen mode Exit fullscreen mode

Sound familiar? Writing test data is:

  • Time-consuming
  • Error-prone
  • Mind-numbingly boring
  • Repetitive across projects

The Game Changer

What if you could do this instead:

// 1. Apply one plugin userSchema.plugin(mongooseTestFactory); // 2. Generate infinite realistic data const user = User.factory().build(); // Output: { name: "Emma Rodriguez", email: "emma.rodriguez@gmail.com", age: 28, isActive: true } const users = await User.factory(100).create(); // 100 users in the DB! 
Enter fullscreen mode Exit fullscreen mode

That's it. No configuration. No setup. Just intelligent, realistic data.

Meet Mongoose Test Factory

I built this plugin because I was frustrated with existing solutions that required complex configuration or generated unrealistic data. Here's what makes it special:

It's Actually Intelligent

  • Recognizes field names: firstName generates names, userEmail generates emails
  • Respects ALL your Mongoose validators automatically
  • Understands relationships and generates proper ObjectIds

Three Power Modes

// Lightning-fast objects for unit tests const user = User.factory().build(); // Full Mongoose instances with methods/virtuals const user = User.factory().make(); // Persisted to database for integration tests const user = await User.factory().create(); 
Enter fullscreen mode Exit fullscreen mode

TypeScript Lovers Rejoice

interface IUserModel extends mongoose.Model<IUser> { findByEmail(email: string): Promise<IUser | null>; } // Preserves ALL your custom methods + adds factory const User = withFactory<IUser, IUserModel>(UserModel); User.findByEmail('test@example.com'); // Your method User.factory().build(); // Factory magic 
Enter fullscreen mode Exit fullscreen mode

Real-World Example

Here's an e-commerce schema that would take forever to mock manually:

const productSchema = new Schema({ name: { type: String, required: true }, price: { type: Number, min: 0.01, max: 9999.99 }, category: { type: String, enum: ['electronics', 'clothing', 'books'] }, description: String, inStock: { type: Boolean, default: true }, tags: [String], ratings: [{ user: { type: ObjectId, ref: 'User' }, score: { type: Number, min: 1, max: 5 } }] }); productSchema.plugin(mongooseTestFactory); const Product = withFactory(mongoose.model('Product', productSchema)); // Generate 50 products with realistic data, proper prices, // valid categories, and even nested ratings! const products = await Product.factory(50).create(); 
Enter fullscreen mode Exit fullscreen mode

The plugin automatically:

  • Generates product names that make sense
  • Creates prices within your min/max range
  • Picks valid categories from your enum
  • Builds nested rating objects with proper ObjectIds
  • Ensures all validation rules are met

Performance That Scales

// Need 10,000 test records? No problem! await User.factory(10000).create(); // Optimized batch processing // Reproducible tests across your team FactoryPlugin.initialize({ seed: 12345 }); 
Enter fullscreen mode Exit fullscreen mode

The Developer Experience

What developers are saying:

"Went from 30 minutes of setup to 30 seconds. This is magic!"
"Finally, a factory that understands my schema without me explaining it."
"The TypeScript support is chef's kiss"

Try It Right Now!

npm install --save-dev mongoose-test-factory 
Enter fullscreen mode Exit fullscreen mode

Literally 3 lines to get started:

import mongooseTestFactory, { withFactory } from 'mongoose-test-factory'; userSchema.plugin(mongooseTestFactory); const User = withFactory(UserModel); const user = User.factory().build(); // Done! 
Enter fullscreen mode Exit fullscreen mode

Why I Built This

As a full-stack developer, I was spending more time writing test data than actual tests. Every project needed the same boring setup:

  1. Write mock data by hand
  2. Copy-paste across files
  3. Debug when schema changes
  4. Repeat for every model

There had to be a better way.

After trying every existing solution and finding them lacking, I built Mongoose Test Factory with one goal: Make test data generation invisible.

What's Next?

I'm constantly improving based on community feedback:

  • More locale support for international data
  • Advanced relationship handling
  • Custom data generators
  • Performance monitoring

Want to contribute? The project is open source and I'd love your input!

Links:

What do you think? Have you struggled with test data generation? What's your current approach? Let me know in the comments!

If this saves you time, drop a star on GitHub - it means the world to indie developers like me!

Happy coding!

Top comments (0)