با چرخاندن یک نمونه MongoDB در حافظه، آزمایش را سریع و آسان شروع کنید. این بسته شما را در کمترین زمان راه اندازی می کند.
آزمایش مدلهای Mongoose میتواند چالشبرانگیز باشد زیرا باید آزمایشهایی بنویسید که با پایگاه داده واقعی شما تداخل نداشته باشند. بسته سرور حافظه MongoDB یک راه حل ساده ارائه می دهد. این به شما امکان می دهد داده های آزمایشی خود را در حافظه برنامه ذخیره کنید.
در این آموزش شما یک مدل Mongoose ساده ایجاد می کنید و با استفاده از Jest و سرور حافظه MongoDB تست می نویسید.
سرور حافظه MongoDB چیست؟
آخرین چیزی که می خواهید این است که داده های جعلی را در پایگاه داده واقعی خود ذخیره کنید که ممکن است در صورت اتصال به آن در طول آزمایش اتفاق بیفتد. در عوض، میتوانید از یک نمونه MongoDB محلی جداگانه برای ذخیره دادههای خود استفاده کنید. در حالی که این کار می کند، اگر آزمایشات شما روی ابر اجرا شود غیرممکن است. علاوه بر این، اتصال و جستجوی یک پایگاه داده واقعی در طول هر آزمون می تواند گران باشد.
سرور حافظه MongoDB، با این حال، یک سرور MongoDB واقعی را می چرخاند و به شما امکان می دهد داده های آزمایشی را در حافظه ذخیره کنید. از آنجایی که داده ها بر روی یک دیسک فیزیکی نوشته نمی شوند، این کار را سریعتر از استفاده از پایگاه داده محلی MongoDB می کند.
ایجاد مدل Mongoose
مدلهای Mongoose یک رابط برای ارتباط با پایگاه داده MongoDB فراهم میکنند. برای ایجاد آنها، باید آنها را از یک طرحواره Mongoose کامپایل کنید، که مدل داده MongoDB شما را تعریف می کند. این آموزش از یک طرح واره برای یک سند کار استفاده می کند. شامل عنوان و فیلدهای تکمیل شده خواهد بود.
دستور زیر را در ترمینال اجرا کنید تا یک پوشه جدید ایجاد کنید و به آن بروید.
mkdir mongoose-model-test
cd mongoose-model-test
npm را با دستور زیر مقداردهی کنید:
npm init -y
پرچم -y به npm دستور می دهد که یک فایل package.json با مقادیر پیش فرض تولید کند.
برای نصب بسته mongoose این دستور را اجرا کنید:
npm install mongoose
یک فایل جدید به نام todo.model.js ایجاد کنید و طرح todo را تعریف کنید:
const mongoose = require("mongoose")
const { Schema } = mongoose
const TodoSchema = new Schema({
item: {
type: String,
required: true
},
compeleted: {
type: Boolean,
required: true
}
})
در انتهای این فایل، مدل todo را ایجاد و صادر کنید:
module.exports = mongoose.model("Todo", TodoSchema)
برنامه ریزی آزمون ها
هنگام نوشتن تست، می خواهید آنچه را که قرار است تست کنید، از قبل برنامه ریزی کنید. این تضمین می کند که تمام عملکردهای مدل خود را آزمایش می کنید.
از مدل Mongoose که ایجاد کردیم، todo باید شامل یک آیتم از نوع String و یک فیلد تکمیل شده از نوع Boolean باشد. هر دوی این فیلدها الزامی است. این بدان معنی است که حداقل، آزمون ما باید اطمینان حاصل کند:
- موارد معتبر با موفقیت در پایگاه داده ذخیره شدند.
- موارد بدون فیلدهای الزامی ذخیره نمی شوند.
- موارد دارای فیلدهای از نوع نامعتبر ذخیره نمی شوند.
ما این تست ها را در یک بلوک تست می نویسیم زیرا مرتبط هستند. در Jest، این بلوک تست را با استفاده از تابع توصیف تعریف می کنید. مثلا:
describe('Todo Model Test', () => {
// Your tests go here
}
راه اندازی پایگاه داده
برای راه اندازی یک سرور حافظه MongoDB، یک نمونه سرور حافظه Mongo جدید ایجاد کرده و به Mongoose متصل خواهید شد. همچنین توابعی ایجاد خواهید کرد که مسئول حذف تمام مجموعه ها در پایگاه داده و قطع ارتباط با نمونه سرور حافظه Mongo هستند.
برای نصب mongodb-memory-server دستور زیر را اجرا کنید.
npm install mongodb-memory-server
یک فایل جدید به نام setuptestdb.js ایجاد کنید و mongoose و mongodb-memory-server را وارد کنید.
const mongoose = require("mongoose");
const { MongoMemoryServer } = require("mongodb-memory-server");
بعد، یک تابع connectDB() ایجاد کنید. این تابع یک نمونه سرور حافظه Mongo جدید ایجاد می کند و به Mongoose متصل می شود. شما آن را قبل از تمام تست ها اجرا می کنید تا به پایگاه داده تست متصل شوید.
let mongo = null;
const connectDB = async () => {
mongo = await MongoMemoryServer.create();
const uri = mongo.getUri();
await mongoose.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
};
با افزودن کد زیر یک تابع dropDB() ایجاد کنید. این تابع پایگاه داده را حذف می کند، اتصال Mongoose را می بندد و نمونه سرور حافظه Mongo را متوقف می کند. شما این تابع را پس از پایان اجرای تمام تست ها اجرا خواهید کرد.
const dropDB = async () => {
if (mongo) {
await mongoose.connection.dropDatabase();
await mongoose.connection.close();
await mongo.stop();
}
};
آخرین تابعی که ایجاد می کنید dropCollections () نام دارد. تمام مجموعه های Mongoose ایجاد شده را حذف می کند. بعد از هر آزمون آن را اجرا خواهید کرد.
const dropCollections = async () => {
if (mongo) {
const collections = await mongoose.connection.db.collections();
for (let collection of collections) {
await collection.remove();
}
}
};
در نهایت، توابع conenctDB()، dropDB() و dropCollections() را صادر کنید.
module.exports = { connectDB, dropDB, dropCollections}
نوشتن تست ها
همانطور که گفته شد برای نوشتن تست ها از Jest استفاده خواهید کرد. برای نصب jest دستور زیر را اجرا کنید.
npm install jest
در فایل package.json، jest را پیکربندی کنید. بلوک “اسکریپت” موجود خود را با موارد زیر جایگزین کنید:
"scripts": {
"test": "jest --runInBand --detectOpenHandles"
},
"jest": {
"testEnvironment": "node"
},
یک فایل جدید به نام todo.model.test.js ایجاد کنید و کتابخانه mongoose، مدل todo و توابع conenctDB()، dropDB() و dropCollections() را وارد کنید:
const mongoose = require("mongoose");
const { connectDB, dropDB, dropCollections } = require("./setupdb");
const Todo = require("./todo.model");
قبل از اجرای تمام تست ها باید تابع connectDB() را اجرا کنید. با Jest می توانید از متد () BeforeAll استفاده کنید.
همچنین باید توابع پاکسازی را اجرا کنید. بعد از هر تست، تابع dropCollections() و تابع dropDB() را بعد از تمام تست ها اجرا کنید. شما نیازی به انجام این کار به صورت دستی ندارید و می توانید از متدهای afterEach() و afterAll() از Jest استفاده کنید.
برای راه اندازی و پاکسازی پایگاه داده کد زیر را به فایل todo.model.test.js اضافه کنید.
beforeAll(async () => {
await connectDB();
});
afterAll(async () => {
await dropDB();
});
afterEach(async () => {
await dropCollections();
});
اکنون برای ایجاد تست ها آماده هستید.
اولین آزمایش بررسی می کند که آیا آیتم todo با موفقیت در پایگاه داده درج شده است یا خیر. بررسی میکند که آیا شناسه شی در صفحه ایجاد شده وجود دارد یا خیر و آیا دادههای موجود در آن با دادهای که به پایگاه داده فرستادهاید مطابقت دارد یا خیر.
یک بلوک توصیف ایجاد کنید و کد زیر را اضافه کنید.
describe("Todo Model", () => {
it("should create a todo item successfully", async () => {
let validTodo = {
item: "Do the dishes",
completed: false,
};
const newTodo = await Todo(validTodo);
await newTodo.save();
expect(newTodo._id).toBeDefined();
expect(newTodo.item).toBe(validTodo.item);
expect(newTodo.completed).toBe(validTodo.completed);
});
});
این یک سند جدید در پایگاه داده ایجاد می کند که حاوی داده های متغیر validTodo است. سپس شیء برگشتی در برابر مقادیر مورد انتظار اعتبارسنجی می شود. برای اینکه این تست بگذرد، مقدار برگشتی باید یک شناسه شی داشته باشد. همچنین، مقادیر موجود در آیتم و فیلدهای تکمیل شده باید با مقادیر موجود در شی validTodo مطابقت داشته باشند.
به غیر از آزمایش موارد استفاده معمولی، شما همچنین باید یک مورد استفاده ناموفق را آزمایش کنید. از آزمایشهایی که ما برنامهریزی کردهایم، باید مدل mongoose را با یک شی todo، با یک فیلد الزامی گمشده و یکی با نوع نادرست آزمایش کنید.
آزمایش دوم را به همان بلوک توصیف اضافه کنید، به شرح زیر:
it("should fail for todo item without required fields", async () => {
let invalidTodo = {
item: "Do the dishes",
};
try {
const newTodo = new Todo(invalidTodo);
await newTodo.save();
} catch (error) {
expect(error).toBeInstanceOf(mongoose.Error.ValidationError);
expect(error.errors.completed).toBeDefined();
}
});
مدل Todo mongoose هم مورد و هم فیلدهای تکمیل شده را انتظار دارد. اگر میخواهید کاری را بدون یکی از این فیلدها ذخیره کنید، باید با خطا مواجه شود. این تست از بلوک try…catch برای گرفتن خطای پرتاب شده استفاده می کند. آزمون انتظار دارد که خطاها یک خطای اعتبارسنجی غول پیکر باشد و از فیلد تکمیل شده گمشده ناشی شود.
برای آزمایش اینکه اگر از مقادیری از نوع اشتباه استفاده می کنید، آیا مدل خطا می دهد یا خیر، کد زیر را به بلوک توصیف اضافه کنید.
it("should fail for todo item with fields of wrong type", async () => {
let invalidTodo = {
item: "Do the dishes",
completed: "False"
};
try {
const newTodo = new Todo(invalidTodo);
await newTodo.save();
} catch (error) {
expect(error).toBeInstanceOf(mongoose.Error.ValidationError);
expect(error.errors.completed).toBeDefined();
}
});
توجه داشته باشید که مقدار فیلد تکمیل شده یک رشته به جای یک بولی است. آزمون انتظار دارد که یک خطای اعتبارسنجی داده شود زیرا مدل انتظار یک مقدار بولی را دارد.
MongoMemoryServer و Jest یک تیم عالی می سازند
بسته mongo-memory-server npm یک راه حل آسان برای آزمایش مدل های Mongoose ارائه می دهد. شما می توانید داده های ساختگی را بدون دست زدن به پایگاه داده برنامه خود در حافظه ذخیره کنید.
میتوانید از MongoMemoryServer با Jest برای نوشتن تستهای مدلهای Mongoose استفاده کنید. توجه داشته باشید که تمام تست های ممکنی که می توانید برای مدل های خود بنویسید را پوشش نمی دهد. آن تست ها به طرح شما بستگی دارد.