---
title: "بيانات اختبار تقول الحقيقة"
description: "الـ fixtures تكذب بالإغفال. mongoose-test-factory يقرأ مخطّطك ويولّد بيانات تحترمه. كيف يقرّر ما يولّده، والأنماط الثلاثة التي أستعملها كل يوم."
date: 2026-08-12
tags: ["mongodb", "اختبارات", "typescript"]
language: ar
canonical: https://aissamirhir.com/ar/blog/test-data-that-tells-the-truth
source: aissamirhir.com
---
كل مشروع Mongoose انضممت إليه كان فيه مجلد `fixtures/`، وكل واحد من تلك المجلدات كان خاطئًا بهدوء. حقل أُضيف إلى المخطّط ولم يُضَف إلى JSON. تعداد (enum) اكتسب قيمة لم يختبرها أحد. علامة `required` ظهرت فتوقّف نصف الـ fixtures عن الحفظ، فوسم أحدهم الاختبار بـ `skip` ومضى.

الـ fixtures لقطة لما كان عليه المخطّط يوم كُتبت. أما المخطّط فهو ما تعتقده الشيفرة اليوم. وُجد [mongoose-test-factory](https://www.npmjs.com/package/mongoose-test-factory) ليغلق تلك الفجوة: يقرأ المخطّط ويولّد بيانات صالحة بحسبه، الآن.

## ابدأ من المخطّط

الحزمة إضافة (plugin). طبّقها، غلّف النموذج، فيحصل النموذج على `factory()`.

```typescript title="user.model.ts"
import mongoose, { Schema } from 'mongoose'
import mongooseTestFactory, { withFactory } from 'mongoose-test-factory'

const userSchema = new Schema({
  name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  age: { type: Number, min: 18, max: 120 },
  isActive: { type: Boolean, default: true },
})

userSchema.plugin(mongooseTestFactory)
export const User = withFactory(mongoose.model('User', userSchema))
```

```typescript
const user = User.factory().build()
// { name: 'John Doe', email: 'john.doe@example.com', age: 28, isActive: true }
```

لم يُضبط شيء. مشت الإضافة على المخطّط، فرأت سلسلة إلزامية باسم `name`، وسلسلة فريدة باسم `email`، ورقمًا محصورًا بين 18 و120، وولّدت وفق ذلك. غيّر المخطّط فيتغيّر التشغيل التالي معه.

## كيف يقرّر ما يولّده

ثلاث طبقات، بترتيب الأولوية.

1. **`factoryType` صريح** على الحقل يفوز. نحو أربعين نوعًا مدمجًا: `email` و`phone` و`price` و`slug` و`uuid` و`birthdate` و`tags` وغيرها.
2. **اسم الحقل.** `userEmail` و`contactEmail` و`email` كلها تبدو بريدًا إلكترونيًا. `price` و`cost` و`amount` تبدو مالًا. `createdAt` يبدو طابعًا زمنيًا.
3. **النوع ومُحقِّقاته.** `Number` مع `min` و`max` يبقى داخل الحدود. `String` مع `enum` تختار منه. `required` يُحترم دائمًا.

حين يكون الاسم ملتبسًا، قُل ذلك في المخطّط:

```typescript
const productSchema = new Schema({
  name: { type: String, factoryType: 'title' },
  vendor: { type: String, factoryType: 'company' },
  price: { type: Number, factoryType: 'price' },
  isActive: { type: Boolean, factoryType: 'active' }, // true about 80% of the time
  website: { type: String, factoryType: 'url' },
})
```

> [!TIP]
> أسماء الحقول ذات المعنى تُجزي مرتين. يقرأها المصنع ليختار مولّدًا، ويقرأها المهندس التالي الذي يفتح الملف. `email` يتفوّق على `str1` عند القارئَين.

## ثلاثة أنماط، ثلاثة أنواع من الاختبارات

| الدالة | تُعيد | تمسّ قاعدة البيانات | استعملها في |
|---|---|---|---|
| `build()` | كائنات عادية | لا | اختبارات الوحدة، أجسام الطلبات |
| `make()` | نُسَخ Mongoose | لا | الحقول الافتراضية، الدوال، الخطافات |
| `create()` | مستندات محفوظة | نعم | اختبارات التكامل |

```typescript
const body = User.factory().build() // fast, no connection needed
const doc = User.factory().make() // an instance, not persisted
const saved = await User.factory(50).create() // fifty real rows
```

معظم اختبارات الوحدة عندي لا تفتح اتصالًا أبدًا. `build()` سريع بما يكفي لأتوقّف كليًا عن تخزين بيانات الاختبار مؤقتًا.

## التجاوزات والعلاقات

القيمة المولّدة نقطة بداية. وما يهمّ الاختبار حقًا، حدّده صراحةً.

```typescript
const admin = User.factory().with({ name: 'Admin', role: 'admin' }).build()

const author = await User.factory().create()
const posts = await Post.factory(5).with({ author: author._id }).create()
```

المثال الثاني هو النمط الذي أستعمله أكثر: أصل واحد حقيقي، وN من الأبناء المولّدين يشيرون إليه. يملأ المصنع كل ما لم أذكره، فتُقرأ التوكيدات كنيّة لا كتحضير.

## ما الذي لن يفعله

لن يخترع قواعد عملك. إذا كان مجموع الطلب يجب أن يساوي مجموع بنوده، فالمخطّط لا يقول ذلك، والمصنع لا يمكنه أن يعرف. اكتب ذلك كتجاوز، أو كمُساعد صغير في إعداد الاختبار يبني طلبات متّسقة. ينبغي للبيانات المولّدة أن تكون صالحة بحسب المخطّط وصادقة فيما عداه؛ والتظاهر بفهم المجال سيكون نوعًا آخر من الكذب.
