تست ماژول‌های ES6 با Jest

داستان چیه؟تا قبل از ES2015، جاوااسکریپت هیچ راهکار مستقیمی برای کار کردن با ماژول‌ها نداشت. که این حفره رو node.js اومد با CommonJS پر کرد. به این صورت که ماژول دلخواهت رو با module.exports می‌فرستی بیرون و هرجایی که با ()require تحویلش بگیری، درواقع اون ماژول رو آوردیش توی فایلت که ازش استفاده کنی.بریم با یه مثال ساده، هم این موارد رو ببینم هم یه تست ساده با Jest انجام بدیم.اولین تست با Jestقبل از هر چیز -با فرض اینکه node روی سیستمتون نصبه- محیط عملیاتیمون رو راه‌اندازی می‌کنیم:npm init -yو بعد Jest رو نصب می‌‌کنیم:npm install --save-dev jestحالا باید دستوری که تست رو برامون اجرا می‌کنه رو به npm معرفی کنیم. داخل فایل package.json دستور مورد نظرمون رو داخل scripts قرار می‌دیم:افزودن دستور دلخواه برای تست کردن با jestتنظیمات اولیه دیگه تموم شد.توی همون پوشه یه فایل به اسم sum.js ایجاد کنید و این فانکشن رو داخلش بنویسید:فانکشن sum که دو عدد a و b را با هم جمع می‌کند در فایل sum.js قرار گرفته‌استاین فانکشن قراره دوتا عدد رو بگیره و حاصل جمع‌شون رو تحویل بده. حالا برای اینکه بتونیم این فانکشن رو با Jest تستش کنیم، نیاز داریم دوتا کار انجام بدیم:لازمه که این فانکشن رو به شکل یه ماژول بفرستیمش بیرون؛ که...... یه جای دیگه بتونیم بگیریمش و تستمون رو روش انجام بدیم⚠ چرا؟!!این درسته که ما می‌تونیم توی یک فایل تستامون رو انجام بدیم. منتها موضوع بحثمون درمورد تست کردن ماژول‌های جاوااسکریپته؛ و من قصد دارم بهتون نشون بدم که از ES2015 به بعد که import/export به جاوااسکریپت اضافه شد، چطوری میشه بدون CommonJS و با همین import/export بتونیم تستمون رو انجام بدیم.پس، همینطوری ماژولار پیش می‌ریمبرای اینکه فانکشنمون رو مثل یه ماژول بفرستیم بیرون، باید این خط رو به انتهای فایل sum.jsمون اضافه کنیم:module.exports = sum;با تغییر اخیر، فایل sum.js آماده تست کردن شد حالا، یک فایل جدید با نام sum.test.js می‌سازیم. این فایل قراره کدهای تست‌مون رو داشته‌باشه. به ساختار اسمش دقت کنید که باید هم‌نام با فایلی باشه که ماژولِ مورد نظرمون داخلشه، و اسم فایل هم باید با test.js تموم بشه.فایل دوم با نام sum.test.js ایجاد شدحالا نیاز داریم که ماژولمون رو توی این فایل دریافت کنیم:ماژول توسط فانکشن require دریافت شداینجا ()require داره اینکار رو برامون انجام میده. حالا نیاز داریم چیزی که اصطلاحاً load کردیم رو نگهش داریم تا بتونیم باهاش کار کنیم:ماژول در متغیر func ذخیره شدالان دیگه فانکشن ()sum داخل func قرار داره. حالا دیگه می‌تونیم فانکشنمون رو با ()func تست کنیم:کد تست نوشته شدتستمون با صدا زدن فانکشن ()test شروع میشه که دوتا پارامتر می‌گیره:اسم تست: کوتاه‌ترین جمله‌ای که نشون بده دارید چه چیزی رو تست می‌کنید. مثلا اسمش رو به انگلیسی بنویسیم "انتظار میره حاصل جمع 1 و 2 برابر با 3 شود". اینطوری وقتی بعد از اجرای تست، کنارش تیک بخوره یا ضربدر بخوره، مثل یک check list، ترتمیز و مرتب می‌بینیم که کدوم تست‌ها قبول شدن (pass) و کدوم تست‌ها رد شدن (failed).فانکشن: فانکشنی رو قرار میدیم که میخواد فرایند تست رو انجام بده، که اینجا مستقیماً یک فانکشن بی‌نام به صورت arrow function قرار دادیم و فرایند تستمون رو داخلش نوشتیم.حالا کافیه دستور زیر رو اجرا کنید تا تست انجام بشه:npm run testدر انتها، ()expect میاد خروجی فانکشنی که بهش دادیم رو نگه میداره و میده بغلی؛ که اینجا بغلیش ()toBe. هستش. ینی الان ()expect اومد حاصل (2 ,1)func رو که برابر با "3" شده، داده به ()toBe. و حالا ()toBe میاد این "3"یی که گرفته رو با چیزی که ما بهش گفتیم مقایسه می‌کنه. اگه یکی باشن، میگه "آفرین درسته" و تستمون pass میشه؛ اگه یکی نباشه می‌گه "زرشک" و تستمون failed میشه!نمایش یک تست موفق در ترمینالتست با import/exportخب، بیاید اول تغییرات لازم رو به کدمون بدیم تا همه چی شبیه ماژولای ES6 بشه. اول بریم exportمون رو تغییر بدیم:و بعد میریم سراغ import کردن ماژولمون توی فایل sum.test.js :الان همه چی به ES6 تغییر کرده. اما اگه دستور تست رو دوباره اجرا کنید، می‌بینید که jest بهتون می‌گه:"بخدای مجید اگه بدونم import چیه؟! یکی بیاد بگه این import چیه @_@"پس، الان نیاز داریم واقعاً بریم "یکی" رو بیاریم که به jest کمک کنه. یه کم به خودتون وقت بدین و یه حدس بزنید، بعد ادامه بدین...راهنما: دنبال اونی می‌گردیم که هیچکدوم از engineهای جاوااسکریپت دستشو رد نمی‎‌‌کنن. اصن شما بیا کد ES12 بنویس، کافیه بدیش به "اون" تا واسط بشه برات، تا همه engineهای جاوااسکریپت اجراش کنن...چیزی که می‌تونه کمکمون کنه Babel هستش. Babel یه پلاگین داره که ماژول‌های ES6 به بعد رو میاد به همون ماژول‌های مدل CommonJS تبدیل می‌کنه. اسمش دقیقاً همین جمله‌ایه که گفتم. پس بریم یه راست نصبش کنیم:npm install --save-dev @babel/plugin-transform-modules-commonjsتنها کار دیگه‌ای که نیاز داریم انجام بدیم اینه که این پلاگین رو به محیط تست‌مون معرفیش کنیم. اینجا منظورم از محیط environment هستش. انگلیسش رو گفتم که راحت‌تر یادتون بمونه:معرفی پلاگین به پروژه - بطور دقیقکلمات انگلیسی رو ببینید که مثل داستان کرده این چند خط کد رو.داریم به package.json می‌گیم که اجازه بده یکی از pluginهای babel وارد محیطِ(env) تستِ(test) من بشه و به jest کمک کنه. مرسی، اه! ?این خیلی دقیق بود، ولی خب شاید بنظر خیلی ترسناک بیاد! می‌تونید ساده‌تر هم بنویسیدش:معرفی پلاگین به پروژه - بطور کلیحالا اگه بریم دوباره تست بگیریم، می‌بینیم که تستمون داره کار می‌کنه ????جمع بندیوقتی Jest کارشو شروع کرد، خیلی مقتدرانه اومد با کمک CommonJS بهمون این امکان رو داد که بتونیم تیکه‌های دلخواه کدمون رو ببریم تست کنیم. بخاطر همین Jest، حداقل در حوزه‌ی Unit Testing حسابی شناخته‌شده هستش.زمان گذشت و JavaScript پیشرفت کرد و خودش قابلیت ماژولار نوشتن رو فراهم کرد. با اینکه همین الان هم Jest داره روی این مسئله کار می‌کنه که بیاد این قابلیت جدید JavaScript رو پوشش بده (تا یه جاهایی هم پیش رفته که امروز که اواخر سال 1400 هستش هنوز در وضعیت آزمایشی قرار داره)، اما هنوز با همون CommonJS داره عملکرد خودش رو معرفی می‌کنه.این مقاله اصلاً به این منظور نوشته نشده که بهتون بگه "از این به بعد باید ماژولای ES6 رو با این روش تست کنید" بلکه این مقاله اونجایی به دردتون می‌خوره که یه کد ES6 (یا جدیدتر) دارید که می‌خواید الان تستش کنید، بدون اینکه بخواید برید سراغ bundlerهایی مثل webpack، parcel، gulp، vite،و یا مجبور باشید همه import/exportهاتون به ساختار CommonJs تغییر بدین